-
+
{t('options.subtitle')}
{existingInstall?.detected ? (
@@ -88,11 +88,11 @@ export function Options({
marginBottom: 16,
padding: '12px 14px',
borderRadius: 10,
- border: '1px solid color-mix(in srgb, var(--color-accent-500) 45%, transparent)',
- background: 'color-mix(in srgb, var(--color-accent-500) 8%, transparent)',
+ border: '1px solid color-mix(in srgb, var(--bf-color-accent-default) 45%, transparent)',
+ background: 'color-mix(in srgb, var(--bf-color-accent-default) 8%, transparent)',
fontSize: 12,
lineHeight: 1.55,
- color: 'var(--color-text-primary)',
+ color: 'var(--bf-color-content-primary)',
}}
>
{t('options.existingInstallTitle')}
@@ -107,7 +107,7 @@ export function Options({
) : null}
{!existingInstall.mainBinaryPresent ? (
-
+
{t('options.existingInstallBinaryMissing')}
) : null}
@@ -173,7 +173,7 @@ export function Options({
gap: 16,
marginTop: 8,
fontSize: 11,
- color: 'var(--color-text-muted)',
+ color: 'var(--bf-color-content-muted)',
opacity: 0.7,
flexWrap: 'wrap',
}}
@@ -184,7 +184,7 @@ export function Options({
{diskSpace.available < Number.MAX_SAFE_INTEGER ? formatBytes(diskSpace.available) : '-'}
{!diskSpace.sufficient && (
-
{t('options.insufficientSpace')}
+
{t('options.insufficientSpace')}
)}
)}
diff --git a/BitFun-Installer/src/pages/Progress.tsx b/BitFun-Installer/src/pages/Progress.tsx
index 9d6e341180..556999a27c 100644
--- a/BitFun-Installer/src/pages/Progress.tsx
+++ b/BitFun-Installer/src/pages/Progress.tsx
@@ -44,10 +44,10 @@ export function ProgressPage({
>
{!error ? (
<>
-
+
{t('progress.title')}
-
+
{stepLabel}
@@ -59,7 +59,7 @@ export function ProgressPage({
gap: 8,
marginTop: 8,
fontSize: 11,
- color: 'var(--color-text-muted)',
+ color: 'var(--bf-color-content-muted)',
opacity: 0.7,
flexWrap: 'wrap',
}}
@@ -76,7 +76,7 @@ export function ProgressPage({
height="18"
viewBox="0 0 24 24"
fill="none"
- stroke="var(--color-error)"
+ stroke="var(--bf-color-status-danger-content)"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
@@ -84,7 +84,7 @@ export function ProgressPage({
>
-
{t('progress.failed')}
+
{t('progress.failed')}
>
)}
diff --git a/BitFun-Installer/src/pages/ThemeSetup.tsx b/BitFun-Installer/src/pages/ThemeSetup.tsx
index 1cd209eda0..4d6cfc907b 100644
--- a/BitFun-Installer/src/pages/ThemeSetup.tsx
+++ b/BitFun-Installer/src/pages/ThemeSetup.tsx
@@ -30,8 +30,8 @@ export function ThemeSetup({ options, setOptions, onLaunch, onClose }: ThemeSetu
borderRadius: 12,
padding: 8,
background: active
- ? 'color-mix(in srgb, var(--color-accent-500) 8%, transparent)'
- : 'var(--element-bg-subtle)',
+ ? 'color-mix(in srgb, var(--bf-color-accent-default) 8%, transparent)'
+ : 'var(--bf-color-surface-subtle)',
border: 'none',
cursor: 'pointer',
transition: 'background 0.2s ease',
@@ -74,7 +74,7 @@ export function ThemeSetup({ options, setOptions, onLaunch, onClose }: ThemeSetu
{t('themeSetup.subtitle')}
@@ -98,7 +98,7 @@ export function ThemeSetup({ options, setOptions, onLaunch, onClose }: ThemeSetu
-
+
{t('themeSetup.followSystem')}
@@ -115,7 +115,7 @@ export function ThemeSetup({ options, setOptions, onLaunch, onClose }: ThemeSetu
-
+
{t(`themeSetup.themeNames.${theme.id}`, { defaultValue: theme.name })}
@@ -132,7 +132,7 @@ export function ThemeSetup({ options, setOptions, onLaunch, onClose }: ThemeSetu
{finishError && (
): TonePreset {
return {
- subtle: alpha(rgb, alphas[0]),
- base: alpha(rgb, alphas[1]),
+ text: {
+ primary: themeValue(theme, 'color.content.primary'),
+ secondary: themeValue(theme, 'color.content.secondary'),
+ muted: themeValue(theme, 'color.content.muted'),
+ },
+ semantic: {
+ success: themeValue(theme, 'color.status.success.content'),
+ warning: themeValue(theme, 'color.status.warning.content'),
+ error: themeValue(theme, 'color.status.danger.content'),
+ },
+ border: {
+ subtle: themeValue(theme, 'color.border.subtle'),
+ base: themeValue(theme, 'color.border.default'),
+ },
+ element: {
+ subtle: themeValue(theme, 'color.surface.subtle'),
+ soft: themeValue(theme, 'color.action.neutral.surface'),
+ medium: themeValue(theme, 'color.action.neutral.surfacePressed'),
+ },
};
}
-function createElementRamp(rgb: string): ElementColors {
+const DARK_TONE = createTone('dark');
+const LIGHT_TONE = createTone('light');
+
+function createBuiltinInstallerTheme(
+ id: Extract
,
+ name: string,
+ type: Extract,
+): InstallerTheme {
+ const tone = type === 'light' ? LIGHT_TONE : DARK_TONE;
return {
- subtle: alpha(rgb, '0.06'),
- soft: alpha(rgb, '0.12'),
- medium: alpha(rgb, '0.18'),
+ id,
+ name,
+ type,
+ colors: {
+ background: {
+ primary: themeValue(type, 'color.surface.canvas'),
+ secondary: themeValue(type, 'color.surface.panel'),
+ },
+ text: { ...tone.text },
+ accent: themeValue(type, 'color.accent.default'),
+ semantic: { ...tone.semantic },
+ border: { ...tone.border },
+ element: { ...tone.element },
+ },
};
}
-const DARK_TONE: TonePreset = {
- text: { primary: '#e8e8e8', secondary: '#b0b0b0', muted: '#858585' },
- semantic: {
- success: '#34d399',
- warning: '#f59e0b',
- error: '#ef4444',
- },
- border: createBorderRamp('255, 255, 255', ['0.12', '0.18']),
- element: createElementRamp('255, 255, 255'),
-};
-
-const LIGHT_TONE: TonePreset = {
- text: { primary: '#1e293b', secondary: '#3d4f66', muted: '#64748b' },
- semantic: {
- success: '#5b9a6f',
- warning: '#c08c42',
- error: '#c26565',
- },
- border: createBorderRamp('100, 116, 139', ['0.15', '0.22']),
- element: createElementRamp('71, 102, 143'),
-};
-
function createInstallerTheme(seed: ThemeSeed): InstallerTheme {
const tone = seed.type === 'light' ? LIGHT_TONE : DARK_TONE;
@@ -135,23 +149,8 @@ function createInstallerTheme(seed: ThemeSeed): InstallerTheme {
}
export const THEMES: InstallerTheme[] = [
- createInstallerTheme({
- id: 'bitfun-dark',
- name: 'Dark',
- type: 'dark',
- background: {
- primary: DARK_CARD_BACKGROUND,
- secondary: DARK_CARD_SURFACE,
- },
- accent: DEFAULT_BLUE,
- }),
- createInstallerTheme({
- id: 'bitfun-light',
- name: 'Light',
- type: 'light',
- background: { primary: '#f7f8fa', secondary: '#ffffff' },
- accent: '#5a7bb2',
- }),
+ createBuiltinInstallerTheme('bitfun-dark', 'Dark', 'dark'),
+ createBuiltinInstallerTheme('bitfun-light', 'Light', 'light'),
createInstallerTheme({
id: 'bitfun-midnight',
name: 'Midnight',
diff --git a/MiniApp/Demo/git-graph/source/style.css b/MiniApp/Demo/git-graph/source/style.css
index 611feace90..623fe7d462 100644
--- a/MiniApp/Demo/git-graph/source/style.css
+++ b/MiniApp/Demo/git-graph/source/style.css
@@ -1,32 +1,32 @@
/* styles/tokens.css */
/* Git Graph MiniApp — theme tokens (host --bitfun-* when running in BitFun) */
:root {
- --bg: var(--bitfun-bg, #0d1117);
- --bg-surface: var(--bitfun-bg-secondary, #161b22);
- --bg-hover: var(--bitfun-element-hover, #1c2333);
- --bg-active: var(--bitfun-element-bg, #1f2a3d);
- --border: var(--bitfun-border, #30363d);
- --border-light: var(--bitfun-border-subtle, #21262d);
- --text: var(--bitfun-text, #e6edf3);
- --text-sec: var(--bitfun-text-secondary, #8b949e);
- --text-dim: var(--bitfun-text-muted, #484f58);
- --accent: var(--bitfun-accent, #58a6ff);
- --accent-dim: var(--bitfun-accent-hover, #1f6feb);
- --green: var(--bitfun-success, #3fb950);
- --red: var(--bitfun-error, #f85149);
- --orange: var(--bitfun-warning, #d29922);
- --purple: var(--bitfun-info, #bc8cff);
- --branch-1: var(--bitfun-accent, #58a6ff);
- --branch-2: var(--bitfun-success, #3fb950);
- --branch-3: var(--bitfun-info, #bc8cff);
- --branch-4: var(--bitfun-warning, #f0883e);
+ --bg: var(--bitfun-bg);
+ --bg-surface: var(--bitfun-bg-secondary);
+ --bg-hover: var(--bitfun-element-hover);
+ --bg-active: var(--bitfun-element-bg);
+ --border: var(--bitfun-border);
+ --border-light: var(--bitfun-border-subtle);
+ --text: var(--bitfun-text);
+ --text-sec: var(--bitfun-text-secondary);
+ --text-dim: var(--bitfun-text-muted);
+ --accent: var(--bitfun-accent);
+ --accent-dim: var(--bitfun-accent-hover);
+ --green: var(--bitfun-success);
+ --red: var(--bitfun-error);
+ --orange: var(--bitfun-warning);
+ --purple: var(--bitfun-accent-secondary);
+ --branch-1: var(--bitfun-accent);
+ --branch-2: var(--bitfun-success);
+ --branch-3: var(--bitfun-accent-secondary);
+ --branch-4: var(--bitfun-warning);
--branch-5: #f778ba;
--branch-6: #79c0ff;
--branch-7: #56d364;
- --radius: var(--bitfun-radius, 6px);
- --radius-lg: var(--bitfun-radius-lg, 10px);
- --graph-node-stroke: var(--bitfun-bg, #0d1117);
- --graph-uncommitted: var(--text-dim, #808080);
+ --radius: var(--bitfun-radius);
+ --radius-lg: var(--bitfun-radius-lg);
+ --graph-node-stroke: var(--bitfun-bg);
+ --graph-uncommitted: var(--text-dim);
--graph-lane-width: 18px;
--graph-row-height: 28px;
}
@@ -34,7 +34,7 @@
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
- font-family: var(--bitfun-font-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif);
+ font-family: var(--bitfun-font-sans);
font-size: 13px;
color: var(--text);
background: var(--bg);
@@ -70,7 +70,7 @@ body {
text-overflow: ellipsis;
white-space: nowrap;
max-width: 280px;
- font-family: var(--bitfun-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
+ font-family: var(--bitfun-font-mono);
}
.toolbar__branch-filter { position: relative; }
.toolbar__branch-filter .chevron { margin-left: 4px; opacity: .8; }
@@ -85,7 +85,7 @@ body {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: var(--radius);
- box-shadow: 0 8px 24px rgba(0,0,0,.25);
+ box-shadow: var(--bitfun-shadow-overlay);
z-index: 200;
padding: 4px 0;
}
@@ -121,8 +121,8 @@ body {
}
.btn--primary {
background: var(--accent-dim);
- color: #fff;
- border-color: rgba(88,166,255,.4);
+ color: var(--bitfun-text-on-accent);
+ border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}
.btn--primary:hover { background: var(--accent); }
.btn--primary:active { background: var(--accent-dim); }
@@ -177,19 +177,19 @@ body {
line-height: 1.4;
}
.badge--branch {
- background: rgba(88,166,255,.15);
+ background: color-mix(in srgb, var(--accent) 15%, transparent);
color: var(--accent);
- border: 1px solid rgba(88,166,255,.25);
+ border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
}
.badge--status {
- background: rgba(63,185,80,.12);
+ background: color-mix(in srgb, var(--green) 12%, transparent);
color: var(--green);
- border: 1px solid rgba(63,185,80,.2);
+ border: 1px solid color-mix(in srgb, var(--green) 20%, transparent);
}
.badge--status.has-changes {
- background: rgba(210,153,34,.12);
+ background: color-mix(in srgb, var(--orange) 12%, transparent);
color: var(--orange);
- border-color: rgba(210,153,34,.2);
+ border-color: color-mix(in srgb, var(--orange) 20%, transparent);
}
/* ── Empty state ─────────────────── */
@@ -260,7 +260,7 @@ body {
}
.commit-row:hover { background: var(--bg-hover); }
.commit-row.selected { background: var(--bg-active); }
-.commit-row.find-highlight { background: rgba(88,166,255,.15); }
+.commit-row.find-highlight { background: color-mix(in srgb, var(--accent) 15%, transparent); }
.commit-row.compare-selected { box-shadow: inset 0 0 0 2px var(--accent); }
.commit-row.commit-row--stash .graph-node--stash-outer {
fill: none;
@@ -289,7 +289,7 @@ body {
}
.commit-row__hash {
flex-shrink: 0;
- font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
+ font-family: var(--bitfun-font-mono);
font-size: 11px;
color: var(--accent);
width: 56px;
@@ -318,19 +318,19 @@ body {
white-space: nowrap;
}
.ref-tag--head {
- background: rgba(88,166,255,.18);
+ background: color-mix(in srgb, var(--accent) 18%, transparent);
color: var(--accent);
}
.ref-tag--branch {
- background: rgba(63,185,80,.14);
+ background: color-mix(in srgb, var(--green) 14%, transparent);
color: var(--green);
}
.ref-tag--tag {
- background: rgba(210,153,34,.14);
+ background: color-mix(in srgb, var(--orange) 14%, transparent);
color: var(--orange);
}
.ref-tag--remote {
- background: rgba(188,140,255,.14);
+ background: color-mix(in srgb, var(--purple) 14%, transparent);
color: var(--purple);
}
@@ -350,7 +350,7 @@ body {
font-size: 11px;
color: var(--text-dim);
text-align: right;
- font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
+ font-family: var(--bitfun-font-mono);
}
/* styles/graph.css */
@@ -392,7 +392,7 @@ body {
display: flex;
flex-direction: column;
overflow: hidden;
- box-shadow: -4px 0 12px rgba(0,0,0,.08);
+ box-shadow: var(--bitfun-shadow-card);
}
.detail-panel-resizer {
width: 6px;
@@ -485,7 +485,7 @@ body {
flex-shrink: 0;
}
.detail-code-preview__filename {
- font-family: var(--bitfun-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
+ font-family: var(--bitfun-font-mono);
font-size: 12px;
color: var(--text);
overflow: hidden;
@@ -513,7 +513,7 @@ body {
.detail-code-preview__error { color: var(--red); }
.detail-code-preview__diff {
margin: 0;
- font-family: var(--bitfun-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
+ font-family: var(--bitfun-font-mono);
font-size: 11px;
line-height: 1.6;
white-space: pre;
@@ -522,8 +522,8 @@ body {
color: var(--text);
}
.detail-code-preview__diff .diff-line { display: block; }
-.detail-code-preview__diff .diff-line.diff-add { color: var(--green); background: rgba(63,185,80,.08); }
-.detail-code-preview__diff .diff-line.diff-del { color: var(--red); background: rgba(248,81,73,.08); }
+.detail-code-preview__diff .diff-line.diff-add { color: var(--green); background: color-mix(in srgb, var(--green) 8%, transparent); }
+.detail-code-preview__diff .diff-line.diff-del { color: var(--red); background: color-mix(in srgb, var(--red) 8%, transparent); }
.detail-code-preview__diff .diff-line.diff-hunk { color: var(--text-dim); }
.detail-section {
@@ -541,7 +541,7 @@ body {
margin-bottom: 8px;
}
.detail-hash {
- font-family: var(--bitfun-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
+ font-family: var(--bitfun-font-mono);
font-size: 12px;
color: var(--accent);
word-break: break-all;
@@ -588,7 +588,7 @@ body {
background: var(--bg);
border-radius: var(--radius);
border: 1px solid var(--border-light);
- font-family: var(--bitfun-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
+ font-family: var(--bitfun-font-mono);
font-size: 11px;
line-height: 1.5;
white-space: pre-wrap;
@@ -597,8 +597,8 @@ body {
overflow: auto;
}
.diff-line { display: block; }
-.diff-line.diff-add { color: var(--green); background: rgba(63,185,80,.08); }
-.diff-line.diff-del { color: var(--red); background: rgba(248,81,73,.08); }
+.diff-line.diff-add { color: var(--green); background: color-mix(in srgb, var(--green) 8%, transparent); }
+.diff-line.diff-del { color: var(--red); background: color-mix(in srgb, var(--red) 8%, transparent); }
.diff-line.diff-hunk { color: var(--text-dim); }
.detail-file__name {
flex: 1;
@@ -606,7 +606,7 @@ body {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
- font-family: var(--bitfun-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
+ font-family: var(--bitfun-font-mono);
color: var(--text-sec);
}
.detail-file__stat { display: flex; gap: 6px; flex-shrink: 0; font-size: 11px; }
@@ -651,7 +651,7 @@ body {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: var(--radius);
- box-shadow: 0 4px 16px rgba(0,0,0,.2);
+ box-shadow: var(--bitfun-shadow-overlay);
}
.find-widget__input {
width: 220px;
@@ -680,7 +680,7 @@ body {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: var(--radius);
- box-shadow: 0 8px 24px rgba(0,0,0,.3);
+ box-shadow: var(--bitfun-shadow-overlay);
font-size: 12px;
}
.context-menu[aria-hidden="true"] { display: none; }
@@ -722,7 +722,7 @@ body {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
- box-shadow: 0 16px 48px rgba(0,0,0,.35);
+ box-shadow: var(--bitfun-shadow-overlay);
}
.modal-dialog__header {
display: flex;
diff --git a/MiniApp/Demo/git-graph/source/styles/detail-panel.css b/MiniApp/Demo/git-graph/source/styles/detail-panel.css
index 818d96290a..13e37e4edc 100644
--- a/MiniApp/Demo/git-graph/source/styles/detail-panel.css
+++ b/MiniApp/Demo/git-graph/source/styles/detail-panel.css
@@ -11,7 +11,7 @@
display: flex;
flex-direction: column;
overflow: hidden;
- box-shadow: -4px 0 12px rgba(0,0,0,.08);
+ box-shadow: var(--bitfun-shadow-card);
}
.detail-panel-resizer {
width: 6px;
@@ -104,7 +104,7 @@
flex-shrink: 0;
}
.detail-code-preview__filename {
- font-family: var(--bitfun-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
+ font-family: var(--bitfun-font-mono);
font-size: 12px;
color: var(--text);
overflow: hidden;
@@ -132,7 +132,7 @@
.detail-code-preview__error { color: var(--red); }
.detail-code-preview__diff {
margin: 0;
- font-family: var(--bitfun-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
+ font-family: var(--bitfun-font-mono);
font-size: 11px;
line-height: 1.6;
white-space: pre;
@@ -141,8 +141,8 @@
color: var(--text);
}
.detail-code-preview__diff .diff-line { display: block; }
-.detail-code-preview__diff .diff-line.diff-add { color: var(--green); background: rgba(63,185,80,.08); }
-.detail-code-preview__diff .diff-line.diff-del { color: var(--red); background: rgba(248,81,73,.08); }
+.detail-code-preview__diff .diff-line.diff-add { color: var(--green); background: color-mix(in srgb, var(--green) 8%, transparent); }
+.detail-code-preview__diff .diff-line.diff-del { color: var(--red); background: color-mix(in srgb, var(--red) 8%, transparent); }
.detail-code-preview__diff .diff-line.diff-hunk { color: var(--text-dim); }
.detail-section {
@@ -160,7 +160,7 @@
margin-bottom: 8px;
}
.detail-hash {
- font-family: var(--bitfun-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
+ font-family: var(--bitfun-font-mono);
font-size: 12px;
color: var(--accent);
word-break: break-all;
@@ -207,7 +207,7 @@
background: var(--bg);
border-radius: var(--radius);
border: 1px solid var(--border-light);
- font-family: var(--bitfun-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
+ font-family: var(--bitfun-font-mono);
font-size: 11px;
line-height: 1.5;
white-space: pre-wrap;
@@ -216,8 +216,8 @@
overflow: auto;
}
.diff-line { display: block; }
-.diff-line.diff-add { color: var(--green); background: rgba(63,185,80,.08); }
-.diff-line.diff-del { color: var(--red); background: rgba(248,81,73,.08); }
+.diff-line.diff-add { color: var(--green); background: color-mix(in srgb, var(--green) 8%, transparent); }
+.diff-line.diff-del { color: var(--red); background: color-mix(in srgb, var(--red) 8%, transparent); }
.diff-line.diff-hunk { color: var(--text-dim); }
.detail-file__name {
flex: 1;
@@ -225,7 +225,7 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
- font-family: var(--bitfun-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
+ font-family: var(--bitfun-font-mono);
color: var(--text-sec);
}
.detail-file__stat { display: flex; gap: 6px; flex-shrink: 0; font-size: 11px; }
diff --git a/MiniApp/Demo/git-graph/source/styles/layout.css b/MiniApp/Demo/git-graph/source/styles/layout.css
index 866044d095..491ae7c98e 100644
--- a/MiniApp/Demo/git-graph/source/styles/layout.css
+++ b/MiniApp/Demo/git-graph/source/styles/layout.css
@@ -23,7 +23,7 @@
text-overflow: ellipsis;
white-space: nowrap;
max-width: 280px;
- font-family: var(--bitfun-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
+ font-family: var(--bitfun-font-mono);
}
.toolbar__branch-filter { position: relative; }
.toolbar__branch-filter .chevron { margin-left: 4px; opacity: .8; }
@@ -38,7 +38,7 @@
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: var(--radius);
- box-shadow: 0 8px 24px rgba(0,0,0,.25);
+ box-shadow: var(--bitfun-shadow-overlay);
z-index: 200;
padding: 4px 0;
}
@@ -74,8 +74,8 @@
}
.btn--primary {
background: var(--accent-dim);
- color: #fff;
- border-color: rgba(88,166,255,.4);
+ color: var(--bitfun-text-on-accent);
+ border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}
.btn--primary:hover { background: var(--accent); }
.btn--primary:active { background: var(--accent-dim); }
@@ -130,19 +130,19 @@
line-height: 1.4;
}
.badge--branch {
- background: rgba(88,166,255,.15);
+ background: color-mix(in srgb, var(--accent) 15%, transparent);
color: var(--accent);
- border: 1px solid rgba(88,166,255,.25);
+ border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
}
.badge--status {
- background: rgba(63,185,80,.12);
+ background: color-mix(in srgb, var(--green) 12%, transparent);
color: var(--green);
- border: 1px solid rgba(63,185,80,.2);
+ border: 1px solid color-mix(in srgb, var(--green) 20%, transparent);
}
.badge--status.has-changes {
- background: rgba(210,153,34,.12);
+ background: color-mix(in srgb, var(--orange) 12%, transparent);
color: var(--orange);
- border-color: rgba(210,153,34,.2);
+ border-color: color-mix(in srgb, var(--orange) 20%, transparent);
}
/* ── Empty state ─────────────────── */
@@ -213,7 +213,7 @@
}
.commit-row:hover { background: var(--bg-hover); }
.commit-row.selected { background: var(--bg-active); }
-.commit-row.find-highlight { background: rgba(88,166,255,.15); }
+.commit-row.find-highlight { background: color-mix(in srgb, var(--accent) 15%, transparent); }
.commit-row.compare-selected { box-shadow: inset 0 0 0 2px var(--accent); }
.commit-row.commit-row--stash .graph-node--stash-outer {
fill: none;
@@ -242,7 +242,7 @@
}
.commit-row__hash {
flex-shrink: 0;
- font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
+ font-family: var(--bitfun-font-mono);
font-size: 11px;
color: var(--accent);
width: 56px;
@@ -271,19 +271,19 @@
white-space: nowrap;
}
.ref-tag--head {
- background: rgba(88,166,255,.18);
+ background: color-mix(in srgb, var(--accent) 18%, transparent);
color: var(--accent);
}
.ref-tag--branch {
- background: rgba(63,185,80,.14);
+ background: color-mix(in srgb, var(--green) 14%, transparent);
color: var(--green);
}
.ref-tag--tag {
- background: rgba(210,153,34,.14);
+ background: color-mix(in srgb, var(--orange) 14%, transparent);
color: var(--orange);
}
.ref-tag--remote {
- background: rgba(188,140,255,.14);
+ background: color-mix(in srgb, var(--purple) 14%, transparent);
color: var(--purple);
}
@@ -303,5 +303,5 @@
font-size: 11px;
color: var(--text-dim);
text-align: right;
- font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
+ font-family: var(--bitfun-font-mono);
}
diff --git a/MiniApp/Demo/git-graph/source/styles/overlay.css b/MiniApp/Demo/git-graph/source/styles/overlay.css
index 20694046e2..b4960d1674 100644
--- a/MiniApp/Demo/git-graph/source/styles/overlay.css
+++ b/MiniApp/Demo/git-graph/source/styles/overlay.css
@@ -35,7 +35,7 @@
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: var(--radius);
- box-shadow: 0 4px 16px rgba(0,0,0,.2);
+ box-shadow: var(--bitfun-shadow-overlay);
}
.find-widget__input {
width: 220px;
@@ -64,7 +64,7 @@
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: var(--radius);
- box-shadow: 0 8px 24px rgba(0,0,0,.3);
+ box-shadow: var(--bitfun-shadow-overlay);
font-size: 12px;
}
.context-menu[aria-hidden="true"] { display: none; }
@@ -106,7 +106,7 @@
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
- box-shadow: 0 16px 48px rgba(0,0,0,.35);
+ box-shadow: var(--bitfun-shadow-overlay);
}
.modal-dialog__header {
display: flex;
diff --git a/MiniApp/Demo/git-graph/source/styles/tokens.css b/MiniApp/Demo/git-graph/source/styles/tokens.css
index 0f1649176e..6f00ce692b 100644
--- a/MiniApp/Demo/git-graph/source/styles/tokens.css
+++ b/MiniApp/Demo/git-graph/source/styles/tokens.css
@@ -1,31 +1,31 @@
/* Git Graph MiniApp — theme tokens (host --bitfun-* when running in BitFun) */
:root {
- --bg: var(--bitfun-bg, #0d1117);
- --bg-surface: var(--bitfun-bg-secondary, #161b22);
- --bg-hover: var(--bitfun-element-hover, #1c2333);
- --bg-active: var(--bitfun-element-bg, #1f2a3d);
- --border: var(--bitfun-border, #30363d);
- --border-light: var(--bitfun-border-subtle, #21262d);
- --text: var(--bitfun-text, #e6edf3);
- --text-sec: var(--bitfun-text-secondary, #8b949e);
- --text-dim: var(--bitfun-text-muted, #484f58);
- --accent: var(--bitfun-accent, #58a6ff);
- --accent-dim: var(--bitfun-accent-hover, #1f6feb);
- --green: var(--bitfun-success, #3fb950);
- --red: var(--bitfun-error, #f85149);
- --orange: var(--bitfun-warning, #d29922);
- --purple: var(--bitfun-info, #bc8cff);
- --branch-1: var(--bitfun-accent, #58a6ff);
- --branch-2: var(--bitfun-success, #3fb950);
- --branch-3: var(--bitfun-info, #bc8cff);
- --branch-4: var(--bitfun-warning, #f0883e);
+ --bg: var(--bitfun-bg);
+ --bg-surface: var(--bitfun-bg-secondary);
+ --bg-hover: var(--bitfun-element-hover);
+ --bg-active: var(--bitfun-element-bg);
+ --border: var(--bitfun-border);
+ --border-light: var(--bitfun-border-subtle);
+ --text: var(--bitfun-text);
+ --text-sec: var(--bitfun-text-secondary);
+ --text-dim: var(--bitfun-text-muted);
+ --accent: var(--bitfun-accent);
+ --accent-dim: var(--bitfun-accent-hover);
+ --green: var(--bitfun-success);
+ --red: var(--bitfun-error);
+ --orange: var(--bitfun-warning);
+ --purple: var(--bitfun-accent-secondary);
+ --branch-1: var(--bitfun-accent);
+ --branch-2: var(--bitfun-success);
+ --branch-3: var(--bitfun-accent-secondary);
+ --branch-4: var(--bitfun-warning);
--branch-5: #f778ba;
--branch-6: #79c0ff;
--branch-7: #56d364;
- --radius: var(--bitfun-radius, 6px);
- --radius-lg: var(--bitfun-radius-lg, 10px);
- --graph-node-stroke: var(--bitfun-bg, #0d1117);
- --graph-uncommitted: var(--text-dim, #808080);
+ --radius: var(--bitfun-radius);
+ --radius-lg: var(--bitfun-radius-lg);
+ --graph-node-stroke: var(--bitfun-bg);
+ --graph-uncommitted: var(--text-dim);
--graph-lane-width: 18px;
--graph-row-height: 28px;
}
@@ -33,7 +33,7 @@
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
- font-family: var(--bitfun-font-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif);
+ font-family: var(--bitfun-font-sans);
font-size: 13px;
color: var(--text);
background: var(--bg);
diff --git a/MiniApp/Demo/git-graph/source/ui.js b/MiniApp/Demo/git-graph/source/ui.js
index cf7c1802b5..86718662a9 100644
--- a/MiniApp/Demo/git-graph/source/ui.js
+++ b/MiniApp/Demo/git-graph/source/ui.js
@@ -122,27 +122,34 @@
const root = document.documentElement;
function getComputed(name) {
- return getComputedStyle(root).getPropertyValue(name).trim() || null;
+ return getComputedStyle(root).getPropertyValue(name).trim();
+ }
+
+ function requireComputed(name) {
+ const value = getComputed(name);
+ if (!value) {
+ throw new Error('Git Graph requires the MiniApp appearance contract variable ' + name + '.');
+ }
+ return value;
}
/** Returns array of 7 branch/lane colors from CSS variables (appearance-aware). */
window.__GG.getGraphColors = function () {
const colors = [];
for (let i = 1; i <= 7; i++) {
- const v = getComputed('--branch-' + i);
- colors.push(v || '#58a6ff');
+ colors.push(requireComputed('--branch-' + i));
}
return colors;
};
/** Node stroke color (contrast with background). */
window.__GG.getNodeStroke = function () {
- return getComputed('--graph-node-stroke') || getComputed('--bitfun-bg') || getComputed('--bg') || '#0d1117';
+ return requireComputed('--graph-node-stroke');
};
/** Uncommitted / WIP line and node color. */
window.__GG.getUncommittedColor = function () {
- return getComputed('--graph-uncommitted') || getComputed('--text-dim') || '#808080';
+ return requireComputed('--graph-uncommitted');
};
})();
diff --git a/MiniApp/Demo/git-graph/source/ui/appearance.js b/MiniApp/Demo/git-graph/source/ui/appearance.js
index 239ee2e055..b6d9a05f49 100644
--- a/MiniApp/Demo/git-graph/source/ui/appearance.js
+++ b/MiniApp/Demo/git-graph/source/ui/appearance.js
@@ -6,26 +6,33 @@
const root = document.documentElement;
function getComputed(name) {
- return getComputedStyle(root).getPropertyValue(name).trim() || null;
+ return getComputedStyle(root).getPropertyValue(name).trim();
+ }
+
+ function requireComputed(name) {
+ const value = getComputed(name);
+ if (!value) {
+ throw new Error('Git Graph requires the MiniApp appearance contract variable ' + name + '.');
+ }
+ return value;
}
/** Returns array of 7 branch/lane colors from CSS variables (appearance-aware). */
window.__GG.getGraphColors = function () {
const colors = [];
for (let i = 1; i <= 7; i++) {
- const v = getComputed('--branch-' + i);
- colors.push(v || '#58a6ff');
+ colors.push(requireComputed('--branch-' + i));
}
return colors;
};
/** Node stroke color (contrast with background). */
window.__GG.getNodeStroke = function () {
- return getComputed('--graph-node-stroke') || getComputed('--bitfun-bg') || getComputed('--bg') || '#0d1117';
+ return requireComputed('--graph-node-stroke');
};
/** Uncommitted / WIP line and node color. */
window.__GG.getUncommittedColor = function () {
- return getComputed('--graph-uncommitted') || getComputed('--text-dim') || '#808080';
+ return requireComputed('--graph-uncommitted');
};
})();
diff --git a/MiniApp/Demo/icon-design-system/source/style.css b/MiniApp/Demo/icon-design-system/source/style.css
index b6d3bf2408..b9023ad997 100644
--- a/MiniApp/Demo/icon-design-system/source/style.css
+++ b/MiniApp/Demo/icon-design-system/source/style.css
@@ -1,36 +1,35 @@
/* ── Theme token aliases ────────────────────────────────────────────────────── */
/* Map --bitfun-* host variables to local names so every rule auto-adapts. */
:root {
- --bg: var(--bitfun-bg, #121214);
- --bg2: var(--bitfun-bg-secondary, #18181a);
- --bg3: var(--bitfun-bg-tertiary, #0e0e10);
- --bg-el: var(--bitfun-element-bg, #27272a);
- --bg-hover: var(--bitfun-element-hover, #3f3f46);
- --text: var(--bitfun-text, #e8e8e8);
- --text2: var(--bitfun-text-secondary, #b0b0b0);
- --text3: var(--bitfun-text-muted, #858585);
- --accent: var(--bitfun-accent, #60a5fa);
- --accent2: var(--bitfun-accent-hover, #3b82f6);
- --success: var(--bitfun-success, #34d399);
- --warning: var(--bitfun-warning, #f59e0b);
- --danger: var(--bitfun-error, #ef4444);
- --info: var(--bitfun-info, #60a5fa);
- --border: var(--bitfun-border, #2e2e32);
- --border2: var(--bitfun-border-subtle, #27272a);
- --radius: var(--bitfun-radius, 6px);
- --radius-lg: var(--bitfun-radius-lg, 10px);
- --font: var(--bitfun-font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif);
- --font-mono: var(--bitfun-font-mono, ui-monospace, monospace);
- --scrollbar: var(--bitfun-scrollbar-thumb, rgba(128,128,128,0.25));
+ --bg: var(--bitfun-bg);
+ --bg2: var(--bitfun-bg-secondary);
+ --bg3: var(--bitfun-bg-tertiary);
+ --bg-el: var(--bitfun-element-bg);
+ --bg-hover: var(--bitfun-element-hover);
+ --text: var(--bitfun-text);
+ --text2: var(--bitfun-text-secondary);
+ --text3: var(--bitfun-text-muted);
+ --accent: var(--bitfun-accent);
+ --accent2: var(--bitfun-accent-hover);
+ --success: var(--bitfun-success);
+ --warning: var(--bitfun-warning);
+ --danger: var(--bitfun-error);
+ --info: var(--bitfun-info);
+ --border: var(--bitfun-border);
+ --border2: var(--bitfun-border-subtle);
+ --radius: var(--bitfun-radius);
+ --radius-lg: var(--bitfun-radius-lg);
+ --font: var(--bitfun-font-sans);
+ --font-mono: var(--bitfun-font-mono);
+ --scrollbar: var(--bitfun-scrollbar-thumb);
/* Derived semantic tokens */
- --on-accent: #fff; /* text on accent-coloured surface */
- --on-danger: #fff; /* text on danger-coloured surface */
- --on-success: #fff; /* text on success-coloured surface */
+ --on-accent: var(--bitfun-text-on-accent);
+ --on-danger: var(--bitfun-text-on-accent);
+ --on-success: var(--bitfun-text-on-accent);
}
-/* In light theme the on-accent/danger text must be white only if the accent is
- dark enough; hosts should override via --bitfun-on-accent if needed. */
+/* On-accent and danger text use the registered --bitfun-text-on-accent projection. */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
diff --git a/design-system/apps/design-lab/src/App.tsx b/design-system/apps/design-lab/src/App.tsx
index 00d11a5445..7a914d637f 100644
--- a/design-system/apps/design-lab/src/App.tsx
+++ b/design-system/apps/design-lab/src/App.tsx
@@ -383,10 +383,12 @@ export function App() {
|| Boolean(activeComponent && activeComponent.category !== "flow-chat");
return (
-
}
-
+
);
}
diff --git a/design-system/apps/design-lab/src/preview/FlowChatPreviewRegistry.tsx b/design-system/apps/design-lab/src/preview/FlowChatPreviewRegistry.tsx
index e9999508c5..237aab7d44 100644
--- a/design-system/apps/design-lab/src/preview/FlowChatPreviewRegistry.tsx
+++ b/design-system/apps/design-lab/src/preview/FlowChatPreviewRegistry.tsx
@@ -324,7 +324,7 @@ function FrameworkPreview({
actions={actions}
content={(
- curl -s -o /dev/null -w "HTTP %{http_code}" https://openbitfun.com
+ {'curl -s -o /dev/null -w "HTTP %{http_code}" https://openbitfun.com'}
)}
extra={(
diff --git a/design-system/apps/design-lab/src/styles.css b/design-system/apps/design-lab/src/styles.css
index b8822b88a2..505e6b9cff 100644
--- a/design-system/apps/design-lab/src/styles.css
+++ b/design-system/apps/design-lab/src/styles.css
@@ -1,7 +1,4 @@
:root {
- font-family: var(--bf-font-family-sans);
- color: #181818;
- background: #ffffff;
font-synthesis: none;
text-rendering: optimizeLegibility;
}
@@ -41,47 +38,12 @@ body,
}
.lab-shell {
- --lab-bg: #ffffff;
- --lab-surface: #ffffff;
- --lab-surface-subtle: #f7f7f7;
- --lab-surface-hover: #f2f2f2;
- --lab-surface-selected: #ededed;
- --lab-border: #e6e6e6;
- --lab-border-strong: #d8d8d8;
- --lab-text: #171717;
- --lab-text-secondary: #5f6168;
- --lab-text-muted: #85878d;
- --lab-inverse: #ffffff;
- --lab-inverse-bg: #171717;
- --lab-danger: #a7352d;
- --lab-shadow: 0 16px 42px rgb(0 0 0 / 0.08);
- --lab-shadow-soft: 0 8px 28px rgb(0 0 0 / 0.05);
-
display: grid;
grid-template-columns: 270px minmax(0, 1fr);
min-height: 100vh;
- color: var(--lab-text);
- background: var(--lab-bg);
-}
-
-.lab-shell[data-lab-scheme="dark"] {
- --lab-bg: #111111;
- --lab-surface: #181818;
- --lab-surface-subtle: #202020;
- --lab-surface-hover: #282828;
- --lab-surface-selected: #303030;
- --lab-border: #303030;
- --lab-border-strong: #404040;
- --lab-text: #f4f4f4;
- --lab-text-secondary: #bcbcbc;
- --lab-text-muted: #888888;
- --lab-inverse: #171717;
- --lab-inverse-bg: #f1f1ee;
- --lab-danger: #ff958b;
- --lab-shadow: 0 18px 48px rgb(0 0 0 / 0.34);
- --lab-shadow-soft: 0 10px 32px rgb(0 0 0 / 0.22);
-
- color-scheme: dark;
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-canvas);
+ font-family: var(--bf-font-family-sans);
}
.lab-sidebar {
@@ -92,8 +54,8 @@ body,
grid-template-rows: auto minmax(0, 1fr) auto;
height: 100vh;
overflow: hidden;
- border-right: 1px solid var(--lab-border);
- background: var(--lab-surface);
+ border-right: 1px solid var(--bf-color-border-subtle);
+ background: var(--bf-color-surface-panel);
}
.lab-sidebar-backdrop {
@@ -107,7 +69,7 @@ body,
gap: 11px;
min-height: 74px;
padding: 14px 18px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.lab-brand__mark {
@@ -115,9 +77,9 @@ body,
width: 34px;
height: 34px;
place-items: center;
- border: 1px solid var(--lab-border-strong);
+ border: 1px solid var(--bf-color-border-default);
border-radius: 10px;
- background: var(--lab-surface-subtle);
+ background: var(--bf-color-surface-tertiary);
}
.lab-brand > span:nth-child(2) {
@@ -137,7 +99,7 @@ body,
.lab-brand small {
overflow: hidden;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-micro);
text-overflow: ellipsis;
white-space: nowrap;
@@ -165,7 +127,7 @@ body,
.lab-nav-label,
.page-kicker {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-micro);
font-weight: var(--bf-font-weight-semibold);
letter-spacing: var(--bf-letter-spacing-caps);
@@ -190,7 +152,7 @@ body,
min-height: 38px;
padding: 7px 10px;
border-radius: 8px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-xs);
text-decoration: none;
transition: color 120ms ease, background-color 120ms ease;
@@ -198,18 +160,18 @@ body,
.lab-navigation > a:hover,
.lab-component-links a:hover {
- color: var(--lab-text);
- background: var(--lab-surface-hover);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-action-quiet-hover);
}
.lab-navigation a[aria-current="page"] {
- color: var(--lab-text);
- background: var(--lab-surface-selected);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-action-quiet-pressed);
font-weight: var(--bf-font-weight-semibold);
}
.lab-navigation a small {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-2xs);
font-weight: var(--bf-font-weight-medium);
text-transform: capitalize;
@@ -233,10 +195,10 @@ body,
gap: 12px;
margin: 12px;
padding: 10px 12px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 9px;
- color: var(--lab-text-secondary);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-secondary);
+ background: var(--bf-color-surface-tertiary);
font-size: var(--bf-font-size-micro);
text-transform: capitalize;
}
@@ -254,8 +216,8 @@ body,
gap: 10px;
min-height: 74px;
padding: 14px 28px;
- border-bottom: 1px solid var(--lab-border);
- background: var(--lab-surface);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
+ background: var(--bf-color-surface-panel);
}
.topbar-menu-button,
@@ -265,7 +227,7 @@ body,
place-items: center;
padding: 0;
border: 1px solid transparent;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
background: transparent;
cursor: pointer;
}
@@ -283,9 +245,9 @@ body,
.topbar-menu-button:hover,
.topbar-icon-button:hover {
- color: var(--lab-text);
- border-color: var(--lab-border);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-primary);
+ border-color: var(--bf-color-border-subtle);
+ background: var(--bf-color-surface-tertiary);
}
.lab-search {
@@ -297,16 +259,16 @@ body,
min-width: 260px;
height: 42px;
padding: 0 10px 0 14px;
- border: 1px solid var(--lab-border-strong);
+ border: 1px solid var(--bf-color-border-default);
border-radius: 999px;
- color: var(--lab-text-muted);
- background: var(--lab-surface);
+ color: var(--bf-color-content-muted);
+ background: var(--bf-color-surface-panel);
transition: border-color 120ms ease, box-shadow 120ms ease;
}
.lab-search:focus-within {
- border-color: var(--lab-text-muted);
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--lab-text) 8%, transparent);
+ border-color: var(--bf-color-content-muted);
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--bf-color-content-primary) 8%, transparent);
}
.lab-search input {
@@ -315,13 +277,13 @@ body,
padding: 0 10px;
border: 0;
outline: 0;
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
background: transparent;
font-size: var(--bf-font-size-xs);
}
.lab-search input::placeholder {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
}
.lab-search input::-webkit-search-cancel-button {
@@ -330,10 +292,10 @@ body,
.lab-search kbd {
padding: 3px 6px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 6px;
- color: var(--lab-text-muted);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-muted);
+ background: var(--bf-color-surface-tertiary);
font-family:var(--bf-font-family-sans);
font-size: var(--bf-font-size-2xs);
}
@@ -347,10 +309,10 @@ body,
max-height: min(480px, calc(100vh - 110px));
overflow: auto;
padding: 7px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 12px;
- background: var(--lab-surface);
- box-shadow: var(--lab-shadow);
+ background: var(--bf-color-surface-panel);
+ box-shadow: var(--bf-shadow-overlay);
}
.lab-search-results button {
@@ -370,7 +332,7 @@ body,
.lab-search-results button:hover,
.lab-search-results button:focus-visible {
outline: 0;
- background: var(--lab-surface-hover);
+ background: var(--bf-color-action-quiet-hover);
}
.lab-search-results button > span:first-child {
@@ -378,10 +340,10 @@ body,
width: 30px;
height: 30px;
place-items: center;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 8px;
- color: var(--lab-text-secondary);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-secondary);
+ background: var(--bf-color-surface-tertiary);
}
.lab-search-results button > span:last-child {
@@ -390,13 +352,13 @@ body,
}
.lab-search-results strong {
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
font-size: var(--bf-font-size-xs);
}
.lab-search-results small,
.lab-search-results p {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-micro);
}
@@ -414,14 +376,14 @@ body,
}
.topbar-links a {
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
font-size: var(--bf-font-size-xs);
font-weight: var(--bf-font-weight-semibold);
text-decoration: none;
}
.topbar-links a:hover {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
}
.lab-language-control {
@@ -434,15 +396,15 @@ body,
padding: 0 9px;
border: 1px solid transparent;
border-radius: 9px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
background: transparent;
}
.lab-language-control:hover,
.lab-language-control:focus-within {
- border-color: var(--lab-border);
- color: var(--lab-text);
- background: var(--lab-surface-subtle);
+ border-color: var(--bf-color-border-subtle);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-tertiary);
}
.lab-language-control select {
@@ -471,10 +433,10 @@ body,
gap: 13px;
width: 280px;
padding: 16px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 12px;
- background: var(--lab-surface);
- box-shadow: var(--lab-shadow);
+ background: var(--bf-color-surface-panel);
+ box-shadow: var(--bf-shadow-overlay);
}
.lab-settings-panel__heading {
@@ -483,7 +445,7 @@ body,
justify-content: space-between;
gap: 12px;
padding-bottom: 12px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.lab-settings-panel__heading > div {
@@ -497,7 +459,7 @@ body,
.lab-settings-panel__heading span,
.lab-settings-panel label > span {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-micro);
}
@@ -522,10 +484,10 @@ body,
.token-tools select {
min-height: 36px;
padding: 6px 30px 6px 10px;
- border: 1px solid var(--lab-border-strong);
+ border: 1px solid var(--bf-color-border-default);
border-radius: 8px;
- color: var(--lab-text);
- background: var(--lab-surface);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-meta);
}
@@ -535,9 +497,9 @@ body,
justify-content: space-between;
min-height: 36px;
padding: 7px 10px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 8px;
- background: var(--lab-surface-subtle);
+ background: var(--bf-color-surface-tertiary);
font-size: var(--bf-font-size-meta);
cursor: pointer;
}
@@ -548,7 +510,7 @@ body,
height: 20px;
place-items: center;
border-radius: 999px;
- background: var(--lab-surface-selected);
+ background: var(--bf-color-action-quiet-pressed);
font-size: var(--bf-font-size-2xs);
}
@@ -600,7 +562,7 @@ body,
.page-heading p {
max-width: 680px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-sm);
line-height: var(--bf-line-height-relaxed);
}
@@ -613,10 +575,10 @@ body,
gap: 8px;
min-height: 38px;
padding: 8px 14px;
- border: 1px solid var(--lab-border-strong);
+ border: 1px solid var(--bf-color-border-default);
border-radius: 999px;
- color: var(--lab-text);
- background: var(--lab-surface);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-meta);
font-weight: var(--bf-font-weight-semibold);
cursor: pointer;
@@ -624,20 +586,20 @@ body,
.lab-button:hover,
.token-action-row button:hover:not(:disabled) {
- background: var(--lab-surface-hover);
+ background: var(--bf-color-action-quiet-hover);
}
.lab-button--primary,
.token-action-row .token-save-button {
- border-color: var(--lab-inverse-bg);
- color: var(--lab-inverse);
- background: var(--lab-inverse-bg);
+ border-color: var(--bf-color-action-primary-background);
+ color: var(--bf-color-content-inverse);
+ background: var(--bf-color-action-primary-background);
}
.lab-button--primary:hover,
.token-action-row .token-save-button:hover:not(:disabled) {
opacity: 0.88;
- background: var(--lab-inverse-bg);
+ background: var(--bf-color-action-primary-background);
}
.lab-button:focus-visible,
@@ -652,7 +614,7 @@ body,
.token-category-tabs button:focus-visible,
.token-table__row:focus-visible,
.copy-value-row:focus-visible {
- outline: 2px solid var(--lab-text);
+ outline: 2px solid var(--bf-color-content-primary);
outline-offset: 2px;
}
@@ -678,10 +640,10 @@ body,
.page-version {
padding: 5px 10px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 999px;
- color: var(--lab-text-secondary);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-secondary);
+ background: var(--bf-color-surface-tertiary);
font-size: var(--bf-font-size-micro);
font-weight: var(--bf-font-weight-semibold);
}
@@ -698,7 +660,7 @@ body,
.overview-copy p {
max-width: 580px;
margin: 0;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-xl);
line-height: var(--bf-line-height-relaxed);
}
@@ -738,14 +700,14 @@ body,
width: 42px;
height: 42px;
place-items: center;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 999px;
- color: var(--lab-text);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-tertiary);
}
.component-card__category {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-2xs);
letter-spacing: var(--bf-letter-spacing-widest);
text-transform: uppercase;
@@ -758,8 +720,8 @@ body,
gap: 24px;
margin-top: 56px;
padding-top: 22px;
- border-top: 1px solid var(--lab-border);
- color: var(--lab-text-muted);
+ border-top: 1px solid var(--bf-color-border-subtle);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-micro);
}
@@ -768,9 +730,9 @@ body,
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
margin-bottom: 26px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 11px;
- background: var(--lab-surface-subtle);
+ background: var(--bf-color-surface-tertiary);
}
.component-summary-strip > span {
@@ -779,8 +741,8 @@ body,
gap: 6px;
min-height: 58px;
padding: 12px 16px;
- border-right: 1px solid var(--lab-border);
- color: var(--lab-text-secondary);
+ border-right: 1px solid var(--bf-color-border-subtle);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-micro);
}
@@ -789,7 +751,7 @@ body,
}
.component-summary-strip strong {
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
font-size: var(--bf-font-size-lg);
}
@@ -816,7 +778,7 @@ body,
.component-library-section-heading h2 {
margin: 0;
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
font-size: var(--bf-font-size-3xl);
letter-spacing: var(--bf-letter-spacing-tight);
}
@@ -824,7 +786,7 @@ body,
.component-library-section-heading p {
max-width: 720px;
margin: 0;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-sm);
line-height: var(--bf-line-height-base);
}
@@ -968,9 +930,9 @@ body,
gap: 48px;
margin-top: 34px;
padding: 28px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 12px;
- background: var(--lab-surface-subtle);
+ background: var(--bf-color-surface-tertiary);
}
.primitive-note > div {
@@ -979,7 +941,7 @@ body,
}
.primitive-note p {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-xs);
line-height: var(--bf-line-height-spacious);
}
@@ -992,14 +954,14 @@ body,
margin-bottom: 24px;
padding: 0;
border: 0;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
background: transparent;
font-size: var(--bf-font-size-micro);
cursor: pointer;
}
.breadcrumb-back:hover {
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
}
.component-detail-content {
@@ -1012,15 +974,15 @@ body,
display: grid;
grid-template-columns: 220px minmax(0, 1fr);
overflow: hidden;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 12px;
- background: var(--lab-surface);
- box-shadow: var(--lab-shadow-soft);
+ background: var(--bf-color-surface-panel);
+ box-shadow: var(--bf-shadow-menu);
}
.component-config-panel {
- border-right: 1px solid var(--lab-border);
- background: var(--lab-surface-subtle);
+ border-right: 1px solid var(--bf-color-border-subtle);
+ background: var(--bf-color-surface-tertiary);
}
.preview-choice-group {
@@ -1029,7 +991,7 @@ body,
margin: 0;
padding: 17px;
border: 0;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.preview-choice-group:last-child {
@@ -1038,7 +1000,7 @@ body,
.preview-choice-group legend {
padding: 0;
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
font-size: var(--bf-font-size-micro);
font-weight: var(--bf-font-weight-semibold);
}
@@ -1052,19 +1014,19 @@ body,
.preview-choice-group button {
min-height: 29px;
padding: 5px 9px;
- border: 1px solid var(--lab-border-strong);
+ border: 1px solid var(--bf-color-border-default);
border-radius: 7px;
- color: var(--lab-text-secondary);
- background: var(--lab-surface);
+ color: var(--bf-color-content-secondary);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-2xs);
text-transform: capitalize;
cursor: pointer;
}
.preview-choice-group button[data-active] {
- border-color: var(--lab-inverse-bg);
- color: var(--lab-inverse);
- background: var(--lab-inverse-bg);
+ border-color: var(--bf-color-action-primary-background);
+ color: var(--bf-color-content-inverse);
+ background: var(--bf-color-action-primary-background);
}
.component-preview-column {
@@ -1135,8 +1097,8 @@ input.lab-force-focus {
.component-code-panel {
overflow: hidden;
- border-top: 1px solid var(--lab-border);
- background: var(--lab-surface-subtle);
+ border-top: 1px solid var(--bf-color-border-subtle);
+ background: var(--bf-color-surface-tertiary);
}
.component-code-panel__header {
@@ -1146,7 +1108,7 @@ input.lab-force-focus {
gap: 12px;
min-height: 38px;
padding: 7px 12px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
font-size: var(--bf-font-size-2xs);
font-weight: var(--bf-font-weight-semibold);
}
@@ -1156,9 +1118,9 @@ input.lab-force-focus {
align-items: center;
gap: 6px;
padding: 4px 7px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 6px;
- background: var(--lab-surface);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-2xs);
cursor: pointer;
}
@@ -1168,7 +1130,7 @@ input.lab-force-focus {
margin: 0;
overflow: auto;
padding: 16px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-family: var(--bf-font-family-mono);
font-size: var(--bf-font-size-micro);
line-height: var(--bf-line-height-relaxed);
@@ -1183,9 +1145,9 @@ input.lab-force-focus {
.component-guidance-grid > section,
.component-reference-panel {
padding: 20px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 11px;
- background: var(--lab-surface);
+ background: var(--bf-color-surface-panel);
}
.component-guidance-grid > section {
@@ -1213,14 +1175,14 @@ input.lab-force-focus {
display: grid;
grid-template-columns: auto minmax(0, 1fr);
gap: 8px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-micro);
line-height: var(--bf-line-height-comfortable);
}
.component-guidance-grid li svg {
margin-top: 1px;
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
}
.reference-panel__heading {
@@ -1238,7 +1200,7 @@ input.lab-force-focus {
.reference-panel__heading > span,
.text-action {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-2xs);
}
@@ -1246,7 +1208,7 @@ input.lab-force-focus {
justify-self: start;
padding: 0;
border: 0;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
background: transparent;
text-decoration: underline;
text-underline-offset: 3px;
@@ -1256,7 +1218,7 @@ input.lab-force-focus {
.props-table {
min-width: 0;
overflow: auto;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 8px;
}
@@ -1264,7 +1226,7 @@ input.lab-force-focus {
display: grid;
grid-template-columns: minmax(100px, 0.7fr) minmax(240px, 1.5fr) minmax(100px, 0.7fr);
min-width: 540px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.props-table__row:last-child {
@@ -1273,8 +1235,8 @@ input.lab-force-focus {
.props-table__row > * {
padding: 10px 12px;
- border-right: 1px solid var(--lab-border);
- color: var(--lab-text-secondary);
+ border-right: 1px solid var(--bf-color-border-subtle);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-2xs);
}
@@ -1283,11 +1245,11 @@ input.lab-force-focus {
}
.props-table__row--header {
- background: var(--lab-surface-subtle);
+ background: var(--bf-color-surface-tertiary);
}
.props-table__row--header > * {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-family:var(--bf-font-family-sans);
font-weight: var(--bf-font-weight-semibold);
text-transform: uppercase;
@@ -1303,10 +1265,10 @@ input.lab-force-focus {
.token-chip-list code,
.token-owner-list span {
padding: 5px 7px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 6px;
- color: var(--lab-text-secondary);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-secondary);
+ background: var(--bf-color-surface-tertiary);
font-size: var(--bf-font-size-2xs);
}
@@ -1322,10 +1284,10 @@ input.lab-force-focus {
.reference-color-palette {
margin-bottom: 26px;
overflow: hidden;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 12px;
- background: var(--lab-surface);
- box-shadow: var(--lab-shadow-soft);
+ background: var(--bf-color-surface-panel);
+ box-shadow: var(--bf-shadow-menu);
}
.reference-color-palette__heading {
@@ -1334,7 +1296,7 @@ input.lab-force-focus {
justify-content: space-between;
gap: 24px;
padding: 18px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.reference-color-palette__heading > div:first-child {
@@ -1350,7 +1312,7 @@ input.lab-force-focus {
.reference-color-palette__heading p,
.reference-color-palette__contract {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-micro);
line-height: var(--bf-line-height-comfortable);
}
@@ -1363,10 +1325,10 @@ input.lab-force-focus {
.reference-color-palette__summary span {
padding: 5px 7px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 999px;
- color: var(--lab-text-muted);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-muted);
+ background: var(--bf-color-surface-tertiary);
font-size: var(--bf-font-size-3xs);
white-space: nowrap;
}
@@ -1380,7 +1342,7 @@ input.lab-force-focus {
grid-template-columns: 112px minmax(0, 1fr);
min-width: 0;
padding: 14px 16px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.reference-color-scale > header {
@@ -1396,7 +1358,7 @@ input.lab-force-focus {
}
.reference-color-scale > header span {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-3xs);
}
@@ -1406,7 +1368,7 @@ input.lab-force-focus {
grid-auto-flow: column;
min-width: 0;
overflow-x: auto;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 8px;
}
@@ -1415,8 +1377,8 @@ input.lab-force-focus {
grid-template-rows: 38px auto auto;
min-width: 58px;
padding-bottom: 6px;
- border-right: 1px solid var(--lab-border);
- background: var(--lab-surface);
+ border-right: 1px solid var(--bf-color-border-subtle);
+ background: var(--bf-color-surface-panel);
}
.reference-color-step:last-child {
@@ -1426,7 +1388,7 @@ input.lab-force-focus {
.reference-color-step__swatch {
display: block;
width: 100%;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.reference-color-step strong,
@@ -1439,20 +1401,20 @@ input.lab-force-focus {
.reference-color-step strong {
margin-top: 6px;
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
font-size: var(--bf-font-size-3xs);
font-weight: var(--bf-font-weight-semibold);
}
.reference-color-step code {
margin-top: 2px;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-4xs);
}
.reference-color-palette__contract {
padding: 10px 16px;
- background: var(--lab-surface-subtle);
+ background: var(--bf-color-surface-tertiary);
}
.token-page-actions {
@@ -1465,7 +1427,7 @@ input.lab-force-focus {
display: flex;
align-items: center;
gap: 7px;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-2xs);
}
@@ -1473,16 +1435,16 @@ input.lab-force-focus {
width: 7px;
height: 7px;
border-radius: 999px;
- background: var(--lab-text-muted);
+ background: var(--bf-color-content-muted);
}
.token-source-status > span:first-child[data-ready] {
- background: var(--lab-text);
+ background: var(--bf-color-content-primary);
}
.token-save-error,
.token-error {
- color: var(--lab-danger);
+ color: var(--bf-color-status-danger-content);
font-size: var(--bf-font-size-2xs);
}
@@ -1507,7 +1469,7 @@ input.lab-force-focus {
.token-edit-count {
margin-right: 4px;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-2xs);
}
@@ -1517,7 +1479,7 @@ input.lab-force-focus {
overflow-x: auto;
margin-bottom: 0;
padding: 0 10px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.token-category-tabs button {
@@ -1525,15 +1487,15 @@ input.lab-force-focus {
padding: 11px 9px 10px;
border: 0;
border-bottom: 2px solid transparent;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
background: transparent;
font-size: var(--bf-font-size-micro);
cursor: pointer;
}
.token-category-tabs button[data-active] {
- border-bottom-color: var(--lab-text);
- color: var(--lab-text);
+ border-bottom-color: var(--bf-color-content-primary);
+ color: var(--bf-color-content-primary);
font-weight: var(--bf-font-weight-semibold);
}
@@ -1542,18 +1504,18 @@ input.lab-force-focus {
grid-template-columns: minmax(0, 1fr) 344px;
min-height: 650px;
margin-top: 0;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-top: 0;
border-radius: 0 0 12px 12px;
- background: var(--lab-surface);
- box-shadow: var(--lab-shadow-soft);
+ background: var(--bf-color-surface-panel);
+ box-shadow: var(--bf-shadow-menu);
}
.token-catalog-panel {
display: grid;
grid-template-rows: auto minmax(0, 1fr);
min-width: 0;
- border-right: 1px solid var(--lab-border);
+ border-right: 1px solid var(--bf-color-border-subtle);
}
.token-tools {
@@ -1561,7 +1523,7 @@ input.lab-force-focus {
grid-template-columns: minmax(220px, 1fr) minmax(130px, 0.45fr) minmax(150px, 0.55fr);
gap: 8px;
padding: 14px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.token-search-field {
@@ -1570,10 +1532,10 @@ input.lab-force-focus {
align-items: center;
min-height: 36px;
padding: 0 10px;
- border: 1px solid var(--lab-border-strong);
+ border: 1px solid var(--bf-color-border-default);
border-radius: 8px;
- color: var(--lab-text-muted);
- background: var(--lab-surface);
+ color: var(--bf-color-content-muted);
+ background: var(--bf-color-surface-panel);
}
.token-search-field input {
@@ -1582,7 +1544,7 @@ input.lab-force-focus {
padding: 0 8px;
border: 0;
outline: 0;
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
background: transparent;
font-size: var(--bf-font-size-micro);
}
@@ -1603,9 +1565,9 @@ input.lab-force-focus {
.token-table__header {
min-height: 40px;
padding: 0 14px;
- border-bottom: 1px solid var(--lab-border);
- color: var(--lab-text-muted);
- background: var(--lab-surface-subtle);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
+ color: var(--bf-color-content-muted);
+ background: var(--bf-color-surface-tertiary);
font-size: var(--bf-font-size-2xs);
font-weight: var(--bf-font-weight-semibold);
}
@@ -1621,20 +1583,20 @@ input.lab-force-focus {
min-height: 58px;
padding: 0 14px;
border: 0;
- border-bottom: 1px solid var(--lab-border);
- color: var(--lab-text);
- background: var(--lab-surface);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-panel);
text-align: left;
cursor: pointer;
}
.token-table__row:hover {
- background: var(--lab-surface-hover);
+ background: var(--bf-color-action-quiet-hover);
}
.token-table__row[data-active] {
- background: var(--lab-surface-selected);
- box-shadow: inset 2px 0 var(--lab-text);
+ background: var(--bf-color-action-quiet-pressed);
+ box-shadow: inset 2px 0 var(--bf-color-content-primary);
}
.token-table__row[data-edited]::after {
@@ -1644,7 +1606,7 @@ input.lab-force-focus {
width: 6px;
height: 6px;
border-radius: 999px;
- background: var(--lab-text);
+ background: var(--bf-color-content-primary);
content: "";
}
@@ -1671,7 +1633,7 @@ input.lab-force-focus {
.token-table__row code {
overflow: hidden;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-family: var(--bf-font-family-mono);
font-size: var(--bf-font-size-2xs);
text-overflow: ellipsis;
@@ -1679,15 +1641,15 @@ input.lab-force-focus {
}
.token-table__row > span:last-child {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-2xs);
}
.token-table__row > span:last-child i {
padding: 2px 5px;
- border: 1px solid var(--lab-border-strong);
+ border: 1px solid var(--bf-color-border-default);
border-radius: 999px;
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
font-size: var(--bf-font-size-3xs);
font-style: normal;
}
@@ -1696,7 +1658,7 @@ input.lab-force-focus {
flex: 0 0 auto;
width: 24px;
height: 24px;
- border: 1px solid var(--lab-border-strong);
+ border: 1px solid var(--bf-color-border-default);
border-radius: 6px;
}
@@ -1707,8 +1669,8 @@ input.lab-force-focus {
gap: 16px;
min-height: 42px;
padding: 8px 14px;
- color: var(--lab-text-muted);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-muted);
+ background: var(--bf-color-surface-tertiary);
font-size: var(--bf-font-size-2xs);
text-transform: capitalize;
}
@@ -1718,7 +1680,7 @@ input.lab-force-focus {
min-height: 220px;
place-items: center;
padding: 24px;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-micro);
text-align: center;
}
@@ -1732,13 +1694,13 @@ input.lab-force-focus {
min-width: 0;
max-height: calc(100vh - 112px);
overflow: auto;
- background: var(--lab-surface);
+ background: var(--bf-color-surface-panel);
}
.token-inspector__heading,
.token-inspector__section {
padding: 18px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.token-inspector__heading {
@@ -1765,10 +1727,10 @@ input.lab-force-focus {
align-items: center;
gap: 4px;
padding: 4px 6px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 999px;
- color: var(--lab-text-secondary);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-secondary);
+ background: var(--bf-color-surface-tertiary);
font-size: var(--bf-font-size-3xs);
}
@@ -1791,12 +1753,12 @@ input.lab-force-focus {
}
.token-inspector__label-row span {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-3xs);
}
.token-inspector p {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-micro);
line-height: var(--bf-line-height-relaxed);
}
@@ -1811,25 +1773,25 @@ input.lab-force-focus {
width: 38px;
height: 38px;
padding: 3px;
- border: 1px solid var(--lab-border-strong);
+ border: 1px solid var(--bf-color-border-default);
border-radius: 8px;
- background: var(--lab-surface);
+ background: var(--bf-color-surface-panel);
}
.token-value-input {
min-width: 0;
height: 38px;
padding: 6px 9px;
- border: 1px solid var(--lab-border-strong);
+ border: 1px solid var(--bf-color-border-default);
border-radius: 8px;
- color: var(--lab-text);
- background: var(--lab-surface);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-panel);
font-family: var(--bf-font-family-mono);
font-size: var(--bf-font-size-micro);
}
.token-value-input[aria-invalid="true"] {
- border-color: var(--lab-danger);
+ border-color: var(--bf-color-status-danger-content);
}
.token-error {
@@ -1844,10 +1806,10 @@ input.lab-force-focus {
min-width: 0;
min-height: 38px;
padding: 7px 9px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 8px;
- color: var(--lab-text-secondary);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-secondary);
+ background: var(--bf-color-surface-tertiary);
cursor: pointer;
}
@@ -1863,7 +1825,7 @@ input.lab-force-focus {
align-items: center;
justify-content: space-between;
gap: 14px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-2xs);
text-transform: capitalize;
}
@@ -1873,7 +1835,7 @@ input.lab-force-focus {
min-height: 260px;
place-items: center;
padding: 32px;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-micro);
line-height: var(--bf-line-height-relaxed);
text-align: center;
@@ -1882,9 +1844,9 @@ input.lab-force-focus {
.token-system-preview {
margin-top: 26px;
overflow: hidden;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 12px;
- box-shadow: var(--lab-shadow-soft);
+ box-shadow: var(--bf-shadow-menu);
}
.token-preview-theme-host {
@@ -2140,7 +2102,7 @@ input.lab-force-focus {
position: static;
grid-template-columns: repeat(2, minmax(0, 1fr));
max-height: none;
- border-top: 1px solid var(--lab-border);
+ border-top: 1px solid var(--bf-color-border-subtle);
}
.token-inspector__heading {
@@ -2148,7 +2110,7 @@ input.lab-force-focus {
}
.token-inspector__section {
- border-right: 1px solid var(--lab-border);
+ border-right: 1px solid var(--bf-color-border-subtle);
}
.token-inspector__meta {
@@ -2179,7 +2141,7 @@ input.lab-force-focus {
inset: 0;
display: block;
border: 0;
- background: rgb(0 0 0 / 0.34);
+ background: var(--bf-color-overlay-scrim);
opacity: 0;
pointer-events: none;
transition: opacity 180ms ease;
@@ -2220,11 +2182,11 @@ input.lab-force-focus {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
border-right: 0;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.preview-choice-group {
- border-right: 1px solid var(--lab-border);
+ border-right: 1px solid var(--bf-color-border-subtle);
border-bottom: 0;
}
@@ -2321,7 +2283,7 @@ input.lab-force-focus {
.component-summary-strip > span {
border-right: 0;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.component-summary-strip > span:last-child {
@@ -2338,7 +2300,7 @@ input.lab-force-focus {
.preview-choice-group {
border-right: 0;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.preview-choice-group:last-child {
@@ -2505,7 +2467,7 @@ input.lab-force-focus {
min-height: 42px;
margin: 14px 20px 24px;
padding: 8px 11px;
- background: var(--lab-surface);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-meta);
}
@@ -2515,7 +2477,7 @@ input.lab-force-focus {
gap: 6px;
padding: 0;
border: 0;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
background: transparent;
font-size: var(--bf-font-size-micro);
text-transform: capitalize;
@@ -2589,7 +2551,7 @@ input.lab-force-focus {
.guide-hero > p {
max-width: 720px;
margin: 0;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-lg);
line-height: var(--bf-line-height-spacious);
}
@@ -2597,9 +2559,9 @@ input.lab-force-focus {
.guide-step-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 12px;
- background: var(--lab-surface);
+ background: var(--bf-color-surface-panel);
}
.guide-step-grid article {
@@ -2609,7 +2571,7 @@ input.lab-force-focus {
gap: 10px;
min-height: 250px;
padding: 28px;
- border-right: 1px solid var(--lab-border);
+ border-right: 1px solid var(--bf-color-border-subtle);
}
.guide-step-grid article:last-child {
@@ -2620,7 +2582,7 @@ input.lab-force-focus {
position: absolute;
top: 24px;
right: 24px;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-family: var(--bf-font-family-mono);
font-size: var(--bf-font-size-micro);
}
@@ -2631,9 +2593,9 @@ input.lab-force-focus {
width: 40px;
height: 40px;
place-items: center;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 10px;
- background: var(--lab-surface-subtle);
+ background: var(--bf-color-surface-tertiary);
}
.guide-step-grid h2 {
@@ -2647,7 +2609,7 @@ input.lab-force-focus {
.guide-next-panel p,
.resource-boundary-panel p {
margin: 0;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-xs);
line-height: var(--bf-line-height-spacious);
}
@@ -2658,9 +2620,9 @@ input.lab-force-focus {
gap: 48px;
align-items: center;
padding: 34px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 12px;
- background: var(--lab-surface-subtle);
+ background: var(--bf-color-surface-tertiary);
}
.guide-contract-copy {
@@ -2687,17 +2649,17 @@ input.lab-force-focus {
display: grid;
grid-template-columns: auto minmax(0, 1fr);
gap: 8px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-meta);
line-height: var(--bf-line-height-comfortable);
}
.guide-code-card {
overflow: hidden;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 10px;
- background: var(--lab-surface);
- box-shadow: var(--lab-shadow-soft);
+ background: var(--bf-color-surface-panel);
+ box-shadow: var(--bf-shadow-menu);
}
.guide-code-card > div {
@@ -2706,8 +2668,8 @@ input.lab-force-focus {
gap: 7px;
min-height: 40px;
padding: 8px 13px;
- border-bottom: 1px solid var(--lab-border);
- color: var(--lab-text-secondary);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-micro);
}
@@ -2715,7 +2677,7 @@ input.lab-force-focus {
margin: 0;
overflow: auto;
padding: 20px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-family: var(--bf-font-family-mono);
font-size: var(--bf-font-size-meta);
line-height: var(--bf-line-height-loose);
@@ -2728,7 +2690,7 @@ input.lab-force-focus {
justify-content: space-between;
gap: 30px;
padding: 28px 0;
- border-top: 1px solid var(--lab-border);
+ border-top: 1px solid var(--bf-color-border-subtle);
}
.guide-next-panel > div,
@@ -2750,7 +2712,7 @@ input.lab-force-focus {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
margin-bottom: 28px;
- border-block: 1px solid var(--lab-border);
+ border-block: 1px solid var(--bf-color-border-subtle);
}
.resource-fact-strip span {
@@ -2759,8 +2721,8 @@ input.lab-force-focus {
gap: 8px;
min-height: 74px;
padding: 18px 24px;
- border-right: 1px solid var(--lab-border);
- color: var(--lab-text-secondary);
+ border-right: 1px solid var(--bf-color-border-subtle);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-xs);
}
@@ -2769,7 +2731,7 @@ input.lab-force-focus {
}
.resource-fact-strip strong {
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
font-size: var(--bf-font-size-4xl);
letter-spacing: var(--bf-letter-spacing-tight);
}
@@ -2787,16 +2749,16 @@ input.lab-force-focus {
gap: 14px;
min-height: 112px;
padding: 20px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 11px;
- color: var(--lab-text);
- background: var(--lab-surface);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-panel);
text-decoration: none;
}
.resource-grid a:hover {
- border-color: var(--lab-border-strong);
- background: var(--lab-surface-subtle);
+ border-color: var(--bf-color-border-default);
+ background: var(--bf-color-surface-tertiary);
}
.resource-grid a > span:nth-child(2) {
@@ -2809,7 +2771,7 @@ input.lab-force-focus {
}
.resource-grid small {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-meta);
line-height: var(--bf-line-height-comfortable);
}
@@ -2845,7 +2807,7 @@ input.lab-force-focus {
gap: clamp(28px, 4vw, 64px);
align-items: start;
padding-block-start: 30px;
- border-block-start: 1px solid var(--lab-border);
+ border-block-start: 1px solid var(--bf-color-border-subtle);
}
.pattern-section__heading {
@@ -2855,7 +2817,7 @@ input.lab-force-focus {
}
.pattern-section__heading > span {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-family: var(--bf-font-family-mono);
font-size: var(--bf-font-size-micro);
}
@@ -2878,7 +2840,7 @@ input.lab-force-focus {
.pattern-section__heading p,
.pattern-navigation-copy p {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-meta);
line-height: var(--bf-line-height-relaxed);
}
@@ -2906,7 +2868,7 @@ input.lab-force-focus {
overflow: hidden;
border: 1px solid var(--bf-color-border-subtle);
border-radius: var(--bf-radius-lg);
- background: var(--bf-color-surface-base);
+ background: var(--bf-color-surface-panel);
}
.pattern-navigation-stage > [data-bf-component="navigation-panel"] {
@@ -3136,7 +3098,7 @@ input.lab-force-focus {
align-items: center;
gap: 7px;
margin-bottom: 14px;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-xs);
}
@@ -3150,7 +3112,7 @@ input.lab-force-focus {
.component-breadcrumb button:hover,
.component-breadcrumb span {
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
}
.component-detail-heading {
@@ -3181,7 +3143,7 @@ input.lab-force-focus {
.component-detail-heading p {
max-width: 680px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-base);
line-height: var(--bf-line-height-comfortable);
}
@@ -3194,10 +3156,10 @@ input.lab-force-focus {
.component-meta-row span {
padding: 4px 7px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 6px;
- color: var(--lab-text-secondary);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-secondary);
+ background: var(--bf-color-surface-tertiary);
font-size: var(--bf-font-size-2xs);
text-transform: capitalize;
}
@@ -3219,7 +3181,7 @@ input.lab-force-focus {
gap: 16px;
min-height: 52px;
padding: 9px 12px 9px 18px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.component-workbench__toolbar > span,
@@ -3243,15 +3205,15 @@ input.lab-force-focus {
gap: 6px;
min-height: 31px;
padding: 6px 9px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 7px;
- background: var(--lab-surface);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-2xs);
cursor: pointer;
}
.component-workbench__toolbar button:hover {
- background: var(--lab-surface-hover);
+ background: var(--bf-color-action-quiet-hover);
}
.component-workbench__body {
@@ -3260,8 +3222,8 @@ input.lab-force-focus {
}
.component-config-panel {
- border-right: 1px solid var(--lab-border);
- background: var(--lab-surface);
+ border-right: 1px solid var(--bf-color-border-subtle);
+ background: var(--bf-color-surface-panel);
}
.preview-choice-group {
@@ -3343,11 +3305,11 @@ input.lab-force-focus {
display: grid;
grid-template-columns: minmax(72px, 0.7fr) minmax(130px, 1.5fr) minmax(70px, 0.7fr);
min-width: 310px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.compact-props-table > div:first-child {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-3xs);
text-transform: uppercase;
}
@@ -3361,7 +3323,7 @@ input.lab-force-focus {
min-width: 0;
overflow-wrap: anywhere;
padding: 7px 5px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-3xs);
}
@@ -3398,7 +3360,7 @@ input.lab-force-focus {
.guide-step-grid article {
min-height: 210px;
border-right: 0;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.guide-step-grid article:last-child {
@@ -3417,7 +3379,7 @@ input.lab-force-focus {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
border-right: 0;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
}
@@ -3449,7 +3411,7 @@ input.lab-force-focus {
.resource-fact-strip span {
min-height: 60px;
border-right: 0;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.resource-fact-strip span:last-child {
@@ -3533,9 +3495,9 @@ input.lab-force-focus {
.component-code-panel--standalone,
.component-inspector {
overflow: hidden;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 10px;
- background: var(--lab-surface);
+ background: var(--bf-color-surface-panel);
}
.component-panel-heading {
@@ -3545,7 +3507,7 @@ input.lab-force-focus {
gap: 20px;
min-height: 72px;
padding: 14px 22px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.component-panel-heading h2 {
@@ -3556,7 +3518,7 @@ input.lab-force-focus {
.component-panel-heading > span,
.component-code-heading span {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-micro);
text-transform: capitalize;
}
@@ -3565,7 +3527,7 @@ input.lab-force-focus {
min-width: 0;
overflow: auto;
color: var(--bf-color-content-primary);
- background: var(--lab-surface);
+ background: var(--bf-color-surface-panel);
}
.component-modal-preview-stage {
@@ -3638,8 +3600,8 @@ input.lab-force-focus {
}
.component-card-media-visual svg {
- inline-size: var(--bf-icon-size-lg);
- block-size: var(--bf-icon-size-lg);
+ inline-size: var(--bf-control-icon-size-lg);
+ block-size: var(--bf-control-icon-size-lg);
}
.component-card-command-grid {
@@ -3989,7 +3951,7 @@ input.lab-force-focus {
border: var(--bf-border-width-default) solid var(--bf-color-border-subtle);
border-radius: var(--bf-radius-md);
color: var(--bf-color-content-primary);
- background: var(--bf-color-surface-default);
+ background: var(--bf-color-surface-panel);
}
.component-icon-catalog__item code {
@@ -4205,8 +4167,8 @@ input.lab-force-focus {
}
.component-code-panel--standalone {
- border-top: 1px solid var(--lab-border);
- background: var(--lab-surface);
+ border-top: 1px solid var(--bf-color-border-subtle);
+ background: var(--bf-color-surface-panel);
}
.component-code-heading > div {
@@ -4221,24 +4183,24 @@ input.lab-force-focus {
gap: 6px;
min-height: 34px;
padding: 6px 10px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 7px;
- color: var(--lab-text);
- background: var(--lab-surface);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-2xs);
cursor: pointer;
}
.component-code-heading button:hover {
- background: var(--lab-surface-hover);
+ background: var(--bf-color-action-quiet-hover);
}
.component-code-panel--standalone pre {
min-height: 320px;
padding: 22px;
border: 0;
- color: var(--lab-text-secondary);
- background: var(--lab-surface);
+ color: var(--bf-color-content-secondary);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-xs);
line-height: var(--bf-line-height-loose);
}
@@ -4257,8 +4219,8 @@ input.lab-force-focus {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
padding: 0 14px;
- border-bottom: 1px solid var(--lab-border);
- background: var(--lab-surface);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
+ background: var(--bf-color-surface-panel);
}
.component-inspector-tabs button {
@@ -4266,14 +4228,14 @@ input.lab-force-focus {
min-height: 68px;
padding: 10px 8px;
border: 0;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
background: transparent;
font-size: var(--bf-font-size-xs);
cursor: pointer;
}
.component-inspector-tabs button[aria-selected="true"] {
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
font-weight: var(--bf-font-weight-semibold);
}
@@ -4283,7 +4245,7 @@ input.lab-force-focus {
left: 50%;
width: 52px;
height: 2px;
- background: var(--lab-text);
+ background: var(--bf-color-content-primary);
content: "";
transform: translateX(-50%);
}
@@ -4291,7 +4253,7 @@ input.lab-force-focus {
.component-inspector-tabs button:focus-visible,
.component-inspector-action:focus-visible,
.component-code-heading button:focus-visible {
- outline: 2px solid var(--lab-text);
+ outline: 2px solid var(--bf-color-content-primary);
outline-offset: -2px;
}
@@ -4303,7 +4265,7 @@ input.lab-force-focus {
display: grid;
gap: 14px;
padding: 20px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.component-inspector-content > section:last-child {
@@ -4326,7 +4288,7 @@ input.lab-force-focus {
grid-template-columns: minmax(82px, 0.7fr) minmax(0, 1.3fr);
align-items: center;
gap: 12px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-meta);
}
@@ -4336,12 +4298,12 @@ input.lab-force-focus {
align-items: center;
gap: 12px;
min-height: 38px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-meta);
}
.component-inspector-toggle [data-bf-component="switch"] {
- --bf-color-control-switch-track-checked: var(--lab-inverse-bg);
+ --bf-color-control-switch-track-checked: var(--bf-color-action-primary-background);
justify-self: end;
}
@@ -4350,10 +4312,10 @@ input.lab-force-focus {
min-width: 0;
height: 38px;
padding: 6px 30px 6px 10px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 8px;
- color: var(--lab-text);
- background: var(--lab-surface);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-xs);
cursor: pointer;
}
@@ -4383,7 +4345,7 @@ input.lab-force-focus {
.component-inspector-props {
display: grid;
- border-block: 1px solid var(--lab-border);
+ border-block: 1px solid var(--bf-color-border-subtle);
}
.component-inspector-props > div {
@@ -4392,7 +4354,7 @@ input.lab-force-focus {
gap: 8px;
align-items: start;
padding: 9px 10px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.component-inspector-props > div:last-child {
@@ -4404,22 +4366,22 @@ input.lab-force-focus {
.component-inspector-props small {
min-width: 0;
overflow-wrap: anywhere;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-3xs);
}
.component-inspector-props code {
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
}
.component-inspector-props small {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
}
.component-inspector-facts {
display: grid;
margin: 0;
- border-block: 1px solid var(--lab-border);
+ border-block: 1px solid var(--bf-color-border-subtle);
}
.component-inspector-facts > div {
@@ -4428,7 +4390,7 @@ input.lab-force-focus {
justify-content: space-between;
gap: 16px;
min-height: 42px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.component-inspector-facts > div:last-child {
@@ -4438,12 +4400,12 @@ input.lab-force-focus {
.component-inspector-facts dt,
.component-inspector-facts dd {
margin: 0;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-micro);
}
.component-inspector-facts dd {
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
font-weight: var(--bf-font-weight-semibold);
text-transform: capitalize;
}
@@ -4458,10 +4420,10 @@ input.lab-force-focus {
.component-inspector-chip-list span,
.component-inspector-token-list code {
padding: 5px 7px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 6px;
- color: var(--lab-text-secondary);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-secondary);
+ background: var(--bf-color-surface-tertiary);
font-size: var(--bf-font-size-3xs);
}
@@ -4477,17 +4439,17 @@ input.lab-force-focus {
.component-inspector-action {
min-height: 36px;
padding: 7px 10px;
- border: 1px solid var(--lab-border-strong);
+ border: 1px solid var(--bf-color-border-default);
border-radius: 8px;
- color: var(--lab-text);
- background: var(--lab-surface);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-micro);
font-weight: var(--bf-font-weight-semibold);
cursor: pointer;
}
.component-inspector-action:hover {
- background: var(--lab-surface-hover);
+ background: var(--bf-color-action-quiet-hover);
}
@media (max-width: 1280px) {
@@ -4557,12 +4519,12 @@ input.lab-force-focus {
align-items: center;
gap: 9px;
margin-bottom: 20px;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-xs);
}
.colors-breadcrumb strong {
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
font-weight: var(--bf-font-weight-semibold);
}
@@ -4593,7 +4555,7 @@ input.lab-force-focus {
}
.colors-heading-copy p {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-base);
line-height: var(--bf-line-height-comfortable);
}
@@ -4610,7 +4572,7 @@ input.lab-force-focus {
display: flex;
align-items: center;
gap: 9px;
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
font-size: var(--bf-font-size-xs);
font-weight: var(--bf-font-weight-semibold);
white-space: nowrap;
@@ -4620,7 +4582,7 @@ input.lab-force-focus {
.colors-filter-field {
position: relative;
display: block;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
}
.colors-select-field select,
@@ -4629,11 +4591,11 @@ input.lab-force-focus {
height: 40px;
appearance: none;
padding: 0 35px 0 12px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 8px;
outline: 0;
- color: var(--lab-text);
- background: var(--lab-surface);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-xs);
cursor: pointer;
}
@@ -4663,14 +4625,8 @@ input.lab-force-focus {
.colors-select-field select:focus-visible,
.colors-filter-field select:focus-visible,
.colors-search-field:focus-within {
- border-color: var(--lab-border-strong);
- box-shadow: 0 0 0 3px rgb(0 0 0 / 0.055);
-}
-
-.lab-shell[data-lab-scheme="dark"] .colors-select-field select:focus-visible,
-.lab-shell[data-lab-scheme="dark"] .colors-filter-field select:focus-visible,
-.lab-shell[data-lab-scheme="dark"] .colors-search-field:focus-within {
- box-shadow: 0 0 0 3px rgb(255 255 255 / 0.08);
+ border-color: var(--bf-color-border-default);
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--bf-color-focus-ring) 18%, transparent);
}
.colors-section-tabs {
@@ -4678,7 +4634,7 @@ input.lab-force-focus {
gap: 28px;
overflow-x: auto;
margin-top: 29px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.colors-section-tabs button {
@@ -4686,21 +4642,21 @@ input.lab-force-focus {
padding: 14px 1px 13px;
border: 0;
border-bottom: 2px solid transparent;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
background: transparent;
font-size: var(--bf-font-size-sm);
cursor: pointer;
}
.colors-section-tabs button[data-active] {
- border-bottom-color: var(--lab-text);
- color: var(--lab-text);
+ border-bottom-color: var(--bf-color-content-primary);
+ color: var(--bf-color-content-primary);
font-weight: var(--bf-font-weight-semibold);
}
.colors-section-tabs button:focus-visible,
.colors-expand-button:focus-visible {
- outline: 2px solid var(--lab-text);
+ outline: 2px solid var(--bf-color-content-primary);
outline-offset: -2px;
}
@@ -4708,9 +4664,9 @@ input.lab-force-focus {
scroll-margin-top: 92px;
margin-top: 16px;
overflow: hidden;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 11px;
- background: var(--lab-surface);
+ background: var(--bf-color-surface-panel);
}
.colors-card-heading {
@@ -4720,7 +4676,7 @@ input.lab-force-focus {
justify-content: space-between;
gap: 24px;
padding: 12px 16px 12px 22px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.colors-card-heading h2 {
@@ -4736,7 +4692,7 @@ input.lab-force-focus {
.colors-card-heading p {
max-width: 760px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-meta);
line-height: var(--bf-line-height-comfortable);
}
@@ -4754,10 +4710,10 @@ input.lab-force-focus {
width: 248px;
height: 40px;
padding: 0 12px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 8px;
- color: var(--lab-text-muted);
- background: var(--lab-surface);
+ color: var(--bf-color-content-muted);
+ background: var(--bf-color-surface-panel);
}
.colors-search-field input {
@@ -4766,13 +4722,13 @@ input.lab-force-focus {
padding: 0 9px;
border: 0;
outline: 0;
- color: var(--lab-text);
+ color: var(--bf-color-content-primary);
background: transparent;
font-size: var(--bf-font-size-xs);
}
.colors-search-field input::placeholder {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
}
.colors-filter-field select {
@@ -4813,8 +4769,8 @@ input.lab-force-focus {
min-width: 0;
height: 48px;
padding: 9px 16px;
- border-right: 1px solid var(--lab-border);
- border-bottom: 1px solid var(--lab-border);
+ border-right: 1px solid var(--bf-color-border-subtle);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
text-align: left;
}
@@ -4824,8 +4780,8 @@ input.lab-force-focus {
.semantic-color-table thead th {
height: 46px;
- color: var(--lab-text-secondary);
- background: var(--lab-surface);
+ color: var(--bf-color-content-secondary);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-meta);
font-weight: var(--bf-font-weight-semibold);
white-space: nowrap;
@@ -4833,7 +4789,7 @@ input.lab-force-focus {
.semantic-color-table tbody th[scope="rowgroup"] {
vertical-align: middle;
- background: var(--lab-surface);
+ background: var(--bf-color-surface-panel);
}
.semantic-color-table tbody th[scope="row"] {
@@ -4841,7 +4797,7 @@ input.lab-force-focus {
}
.semantic-color-table tbody td:last-child {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-meta);
line-height: var(--bf-line-height-base);
}
@@ -4849,7 +4805,7 @@ input.lab-force-focus {
.semantic-color-table code,
.colors-mapping-table code {
overflow-wrap: anywhere;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-family: var(--bf-font-family-mono);
font-size: var(--bf-font-size-micro);
font-weight: var(--bf-font-weight-medium);
@@ -4875,45 +4831,45 @@ input.lab-force-focus {
}
.semantic-color-group small {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-meta);
font-weight: var(--bf-font-weight-regular);
}
.semantic-color-group--surface > i {
- background: #dbeafe;
+ background: var(--bf-color-surface-panel);
}
.semantic-color-group--content > i {
- background: #b6efd4;
+ background: var(--bf-color-content-primary);
}
.semantic-color-group--action > i {
- background: #93c5fd;
+ background: var(--bf-color-action-primary-background);
}
.semantic-color-group--accent > i {
- background: #bfdbfe;
+ background: var(--bf-color-accent-default);
}
.semantic-color-group--border > i {
- background: #c9c9cc;
+ background: var(--bf-color-border-default);
}
.semantic-color-group--field > i {
- background: #ededee;
+ background: var(--bf-color-field-background);
}
.semantic-color-group--control > i {
- background: #83e2b8;
+ background: var(--bf-color-control-switch-track-checked);
}
.semantic-color-group--focus > i {
- background: #60a5fa;
+ background: var(--bf-color-focus-ring);
}
.semantic-color-group--status > i {
- background: #ffdc89;
+ background: var(--bf-color-status-warning-content);
}
.semantic-color-value {
@@ -4927,9 +4883,9 @@ input.lab-force-focus {
flex: 0 0 auto;
width: 19px;
height: 19px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 3px;
- box-shadow: inset 0 0 0 0.5px rgb(0 0 0 / 0.035);
+ box-shadow: var(--bf-shadow-inner-highlight);
}
.semantic-color-value code {
@@ -4940,7 +4896,7 @@ input.lab-force-focus {
.semantic-color-table__empty td {
height: 96px;
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-xs);
text-align: center;
}
@@ -4954,15 +4910,15 @@ input.lab-force-focus {
gap: 9px;
padding: 10px 22px;
border: 0;
- color: var(--lab-text-secondary);
- background: var(--lab-surface);
+ color: var(--bf-color-content-secondary);
+ background: var(--bf-color-surface-panel);
font-size: var(--bf-font-size-meta);
cursor: pointer;
}
.colors-expand-button:hover {
- color: var(--lab-text);
- background: var(--lab-surface-subtle);
+ color: var(--bf-color-content-primary);
+ background: var(--bf-color-surface-tertiary);
}
.colors-expand-button svg {
@@ -4983,7 +4939,7 @@ input.lab-force-focus {
display: flex;
align-items: center;
gap: 10px;
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-meta);
}
@@ -5013,19 +4969,19 @@ input.lab-force-focus {
}
.colors-scale-step strong {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-meta);
font-weight: var(--bf-font-weight-medium);
}
.colors-scale-step > span {
display: block;
- border: 1px solid rgb(0 0 0 / 0.035);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 6px;
}
.colors-scale-step code {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-family: var(--bf-font-family-mono);
font-size: var(--bf-font-size-micro);
}
@@ -5044,7 +5000,7 @@ input.lab-force-focus {
gap: 14px;
min-width: 0;
padding: 13px;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 8px;
}
@@ -5058,7 +5014,7 @@ input.lab-force-focus {
}
.colors-palette-row small {
- color: var(--lab-text-muted);
+ color: var(--bf-color-content-muted);
font-size: var(--bf-font-size-2xs);
}
@@ -5068,7 +5024,7 @@ input.lab-force-focus {
grid-auto-flow: column;
height: 38px;
overflow: hidden;
- border: 1px solid var(--lab-border);
+ border: 1px solid var(--bf-color-border-subtle);
border-radius: 6px;
}
@@ -5088,7 +5044,7 @@ input.lab-force-focus {
.colors-mapping-table td {
height: 46px;
padding: 9px 18px;
- border-bottom: 1px solid var(--lab-border);
+ border-bottom: 1px solid var(--bf-color-border-subtle);
text-align: left;
}
@@ -5101,7 +5057,7 @@ input.lab-force-focus {
}
.colors-mapping-table thead th {
- color: var(--lab-text-secondary);
+ color: var(--bf-color-content-secondary);
font-size: var(--bf-font-size-meta);
font-weight: var(--bf-font-weight-semibold);
}
diff --git a/design-system/apps/design-lab/src/token-editor/TokenWorkbench.tsx b/design-system/apps/design-lab/src/token-editor/TokenWorkbench.tsx
index 266523f2c3..4f71553197 100644
--- a/design-system/apps/design-lab/src/token-editor/TokenWorkbench.tsx
+++ b/design-system/apps/design-lab/src/token-editor/TokenWorkbench.tsx
@@ -1,4 +1,5 @@
import { useEffect, useMemo, useState, type ReactNode } from "react";
+import { themes } from "@bitfun/theme-bitfun";
import {
Check,
Clipboard,
@@ -142,7 +143,9 @@ function TokenValueControl({
className="token-color-picker"
onChange={(event) => onChange(event.target.value)}
type="color"
- value={/^#[0-9a-f]{6}$/i.test(value) ? value : "#000000"}
+ value={/^#[0-9a-f]{6}$/i.test(value)
+ ? value
+ : String(themes.light["color.content.onLight"])}
/>
)}
= 4.5,
);
for (const status of ["info", "success", "warning", "danger"]) {
- // The existing BitFun light Appearance warning pair is 4.38:1. Keep
- // that single migration baseline exact instead of silently restyling
- // the product; all other default and high-contrast pairs remain 4.5:1.
- const minimumContrast = mode === "light" && status === "warning" ? 4.38 : 4.5;
+ const minimumContrast = 4.5;
assert.ok(
contrastRatio(
variant[`color.status.${status}.surface`].value,
diff --git a/design-system/packages/ui/src/components/Icon/assets/arrow-left.svg b/design-system/packages/ui/src/components/Icon/assets/arrow-left.svg
index d4b37e1a6d..f0935e0ec7 100644
--- a/design-system/packages/ui/src/components/Icon/assets/arrow-left.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/arrow-left.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/arrow-right.svg b/design-system/packages/ui/src/components/Icon/assets/arrow-right.svg
index 39b5c0bdd9..ddb167ef4c 100644
--- a/design-system/packages/ui/src/components/Icon/assets/arrow-right.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/arrow-right.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/arrow-up.svg b/design-system/packages/ui/src/components/Icon/assets/arrow-up.svg
index ceaad590a3..1575dee313 100644
--- a/design-system/packages/ui/src/components/Icon/assets/arrow-up.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/arrow-up.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/arrow-upright.svg b/design-system/packages/ui/src/components/Icon/assets/arrow-upright.svg
index a496346fc2..231f9f3c06 100644
--- a/design-system/packages/ui/src/components/Icon/assets/arrow-upright.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/arrow-upright.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/bell.svg b/design-system/packages/ui/src/components/Icon/assets/bell.svg
index 1c2c2a7120..1c9a024434 100644
--- a/design-system/packages/ui/src/components/Icon/assets/bell.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/bell.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/browser.svg b/design-system/packages/ui/src/components/Icon/assets/browser.svg
index 66d925a8e2..119c22548f 100644
--- a/design-system/packages/ui/src/components/Icon/assets/browser.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/browser.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/check-circle.svg b/design-system/packages/ui/src/components/Icon/assets/check-circle.svg
index 79988a8aa9..c0c3345975 100644
--- a/design-system/packages/ui/src/components/Icon/assets/check-circle.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/check-circle.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/check-fill.svg b/design-system/packages/ui/src/components/Icon/assets/check-fill.svg
index 50590d37f2..430a033b5e 100644
--- a/design-system/packages/ui/src/components/Icon/assets/check-fill.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/check-fill.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/check-line.svg b/design-system/packages/ui/src/components/Icon/assets/check-line.svg
index 8fb135d15a..ecd239e9ac 100644
--- a/design-system/packages/ui/src/components/Icon/assets/check-line.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/check-line.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/chevron-down.svg b/design-system/packages/ui/src/components/Icon/assets/chevron-down.svg
index 4dec14ccd3..23f3b909f6 100644
--- a/design-system/packages/ui/src/components/Icon/assets/chevron-down.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/chevron-down.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/chevron-right.svg b/design-system/packages/ui/src/components/Icon/assets/chevron-right.svg
index de41eebaf3..e060378577 100644
--- a/design-system/packages/ui/src/components/Icon/assets/chevron-right.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/chevron-right.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/chevron-up.svg b/design-system/packages/ui/src/components/Icon/assets/chevron-up.svg
index 4eac2397ee..078b2012d6 100644
--- a/design-system/packages/ui/src/components/Icon/assets/chevron-up.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/chevron-up.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/circle.svg b/design-system/packages/ui/src/components/Icon/assets/circle.svg
index 0b643f55ba..0ee57499ad 100644
--- a/design-system/packages/ui/src/components/Icon/assets/circle.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/circle.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/clock.svg b/design-system/packages/ui/src/components/Icon/assets/clock.svg
index c5e6f35ac0..34702f9def 100644
--- a/design-system/packages/ui/src/components/Icon/assets/clock.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/clock.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/command-mac.svg b/design-system/packages/ui/src/components/Icon/assets/command-mac.svg
index 24e6bbb609..474211bef9 100644
--- a/design-system/packages/ui/src/components/Icon/assets/command-mac.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/command-mac.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/commit.svg b/design-system/packages/ui/src/components/Icon/assets/commit.svg
index c0a04e8d3e..c65645f886 100644
--- a/design-system/packages/ui/src/components/Icon/assets/commit.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/commit.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/device-mac.svg b/design-system/packages/ui/src/components/Icon/assets/device-mac.svg
index 7e6515e1f9..f323955e80 100644
--- a/design-system/packages/ui/src/components/Icon/assets/device-mac.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/device-mac.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/download.svg b/design-system/packages/ui/src/components/Icon/assets/download.svg
index 95a245ae82..e5d5f1f738 100644
--- a/design-system/packages/ui/src/components/Icon/assets/download.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/download.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/duplicate.svg b/design-system/packages/ui/src/components/Icon/assets/duplicate.svg
index 31b02cda09..ad7d0ba184 100644
--- a/design-system/packages/ui/src/components/Icon/assets/duplicate.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/duplicate.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/edit.svg b/design-system/packages/ui/src/components/Icon/assets/edit.svg
index df46b32357..6c0b24a84a 100644
--- a/design-system/packages/ui/src/components/Icon/assets/edit.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/edit.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/extension.svg b/design-system/packages/ui/src/components/Icon/assets/extension.svg
index 06fda65a37..dfed7ed920 100644
--- a/design-system/packages/ui/src/components/Icon/assets/extension.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/extension.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/eye.svg b/design-system/packages/ui/src/components/Icon/assets/eye.svg
index adcaddb9ef..5598bf22b8 100644
--- a/design-system/packages/ui/src/components/Icon/assets/eye.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/eye.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/files.svg b/design-system/packages/ui/src/components/Icon/assets/files.svg
index 6c98ca1607..a57f9a3847 100644
--- a/design-system/packages/ui/src/components/Icon/assets/files.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/files.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/filter.svg b/design-system/packages/ui/src/components/Icon/assets/filter.svg
index 3cd4a748f2..00e7f06537 100644
--- a/design-system/packages/ui/src/components/Icon/assets/filter.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/filter.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/floating-window.svg b/design-system/packages/ui/src/components/Icon/assets/floating-window.svg
index c51b9059f8..8c5609a267 100644
--- a/design-system/packages/ui/src/components/Icon/assets/floating-window.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/floating-window.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/folder.svg b/design-system/packages/ui/src/components/Icon/assets/folder.svg
index a3eb294dd0..b559c1ac78 100644
--- a/design-system/packages/ui/src/components/Icon/assets/folder.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/folder.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/gear.svg b/design-system/packages/ui/src/components/Icon/assets/gear.svg
index 69e74b9b00..65399288ae 100644
--- a/design-system/packages/ui/src/components/Icon/assets/gear.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/gear.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/git.svg b/design-system/packages/ui/src/components/Icon/assets/git.svg
index 495f588bb4..a6784f8732 100644
--- a/design-system/packages/ui/src/components/Icon/assets/git.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/git.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/image.svg b/design-system/packages/ui/src/components/Icon/assets/image.svg
index 0e16a96c90..6fd2495f0e 100644
--- a/design-system/packages/ui/src/components/Icon/assets/image.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/image.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/info.svg b/design-system/packages/ui/src/components/Icon/assets/info.svg
index 2c583c972b..d0e463dd00 100644
--- a/design-system/packages/ui/src/components/Icon/assets/info.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/info.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/level.svg b/design-system/packages/ui/src/components/Icon/assets/level.svg
index efb2867766..02cf96ba40 100644
--- a/design-system/packages/ui/src/components/Icon/assets/level.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/level.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/link.svg b/design-system/packages/ui/src/components/Icon/assets/link.svg
index 6b429bed9f..0bfaa0eb27 100644
--- a/design-system/packages/ui/src/components/Icon/assets/link.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/link.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/mic.svg b/design-system/packages/ui/src/components/Icon/assets/mic.svg
index 87184eaab5..4586baf8f1 100644
--- a/design-system/packages/ui/src/components/Icon/assets/mic.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/mic.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/mini-app.svg b/design-system/packages/ui/src/components/Icon/assets/mini-app.svg
index a053675bec..5ae2a4b97b 100644
--- a/design-system/packages/ui/src/components/Icon/assets/mini-app.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/mini-app.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/more.svg b/design-system/packages/ui/src/components/Icon/assets/more.svg
index 63af5adc10..f8fd292ea3 100644
--- a/design-system/packages/ui/src/components/Icon/assets/more.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/more.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/palette.svg b/design-system/packages/ui/src/components/Icon/assets/palette.svg
index 7439b99b1f..42dbf5f17c 100644
--- a/design-system/packages/ui/src/components/Icon/assets/palette.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/palette.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/pin.svg b/design-system/packages/ui/src/components/Icon/assets/pin.svg
index 98224fec3b..2a2c59de89 100644
--- a/design-system/packages/ui/src/components/Icon/assets/pin.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/pin.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/plus.svg b/design-system/packages/ui/src/components/Icon/assets/plus.svg
index 43da3ee9f6..7e510c114d 100644
--- a/design-system/packages/ui/src/components/Icon/assets/plus.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/plus.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/progress-25.svg b/design-system/packages/ui/src/components/Icon/assets/progress-25.svg
index adaaa6b470..deff56f81e 100644
--- a/design-system/packages/ui/src/components/Icon/assets/progress-25.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/progress-25.svg
@@ -1,6 +1,6 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/refresh.svg b/design-system/packages/ui/src/components/Icon/assets/refresh.svg
index a42ac053f4..8f22029228 100644
--- a/design-system/packages/ui/src/components/Icon/assets/refresh.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/refresh.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/search.svg b/design-system/packages/ui/src/components/Icon/assets/search.svg
index 1ff7e056dc..b97f56b236 100644
--- a/design-system/packages/ui/src/components/Icon/assets/search.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/search.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/session.svg b/design-system/packages/ui/src/components/Icon/assets/session.svg
index 8cdde77459..6d73330e4d 100644
--- a/design-system/packages/ui/src/components/Icon/assets/session.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/session.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/settings.svg b/design-system/packages/ui/src/components/Icon/assets/settings.svg
index 63cd895351..9fa37ab47e 100644
--- a/design-system/packages/ui/src/components/Icon/assets/settings.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/settings.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/show-session.svg b/design-system/packages/ui/src/components/Icon/assets/show-session.svg
index 71df9157a9..3dc58b4003 100644
--- a/design-system/packages/ui/src/components/Icon/assets/show-session.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/show-session.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/side-chat.svg b/design-system/packages/ui/src/components/Icon/assets/side-chat.svg
index 08f8ed3e44..85e79159bf 100644
--- a/design-system/packages/ui/src/components/Icon/assets/side-chat.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/side-chat.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/sidebar-left.svg b/design-system/packages/ui/src/components/Icon/assets/sidebar-left.svg
index 67e3619fd1..a70bb22060 100644
--- a/design-system/packages/ui/src/components/Icon/assets/sidebar-left.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/sidebar-left.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/sidebar-right.svg b/design-system/packages/ui/src/components/Icon/assets/sidebar-right.svg
index 8019454813..b7b97ad077 100644
--- a/design-system/packages/ui/src/components/Icon/assets/sidebar-right.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/sidebar-right.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/spark.svg b/design-system/packages/ui/src/components/Icon/assets/spark.svg
index 8ac023b519..daed6c8cec 100644
--- a/design-system/packages/ui/src/components/Icon/assets/spark.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/spark.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/star.svg b/design-system/packages/ui/src/components/Icon/assets/star.svg
index dac3fc6e97..be38a6e18d 100644
--- a/design-system/packages/ui/src/components/Icon/assets/star.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/star.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/store.svg b/design-system/packages/ui/src/components/Icon/assets/store.svg
index 3f06ed29f1..e5b5172403 100644
--- a/design-system/packages/ui/src/components/Icon/assets/store.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/store.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/terminal.svg b/design-system/packages/ui/src/components/Icon/assets/terminal.svg
index 391c9d4fd0..0443452c77 100644
--- a/design-system/packages/ui/src/components/Icon/assets/terminal.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/terminal.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/thinking.svg b/design-system/packages/ui/src/components/Icon/assets/thinking.svg
index 46c0c60c8b..47dc58054b 100644
--- a/design-system/packages/ui/src/components/Icon/assets/thinking.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/thinking.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/turn.svg b/design-system/packages/ui/src/components/Icon/assets/turn.svg
index 9387237fe4..afb8145b3d 100644
--- a/design-system/packages/ui/src/components/Icon/assets/turn.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/turn.svg
@@ -1,3 +1,3 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/upload.svg b/design-system/packages/ui/src/components/Icon/assets/upload.svg
index db786995ef..d166840788 100644
--- a/design-system/packages/ui/src/components/Icon/assets/upload.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/upload.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/user.svg b/design-system/packages/ui/src/components/Icon/assets/user.svg
index f673efe31c..8e2001c4b2 100644
--- a/design-system/packages/ui/src/components/Icon/assets/user.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/user.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/Icon/assets/xmark.svg b/design-system/packages/ui/src/components/Icon/assets/xmark.svg
index b87b7bc232..d8c5f2592d 100644
--- a/design-system/packages/ui/src/components/Icon/assets/xmark.svg
+++ b/design-system/packages/ui/src/components/Icon/assets/xmark.svg
@@ -1,5 +1,5 @@
diff --git a/design-system/packages/ui/src/components/KeyHint/KeyHint.module.css b/design-system/packages/ui/src/components/KeyHint/KeyHint.module.css
index 739c0c6cec..927a2a7507 100644
--- a/design-system/packages/ui/src/components/KeyHint/KeyHint.module.css
+++ b/design-system/packages/ui/src/components/KeyHint/KeyHint.module.css
@@ -10,9 +10,9 @@
padding-block: calc(var(--bf-space-1) / 2);
padding-inline: var(--bf-space-1);
border: 0;
- border-radius: var(--bf-radius-xs, calc(var(--bf-radius-sm) - 2px));
+ border-radius: var(--bf-radius-xs);
color: var(--bf-color-content-muted);
- background: var(--bf-color-key-hint-background, var(--bf-color-action-neutral-surface));
+ background: var(--bf-color-key-hint-background);
font-family:var(--bf-font-family-sans);
font-size: var(--bf-font-size-micro);
font-weight: var(--bf-font-weight-regular);
diff --git a/design-system/packages/ui/src/flow-chat/tool-cards/FlowChatToolCard.module.css b/design-system/packages/ui/src/flow-chat/tool-cards/FlowChatToolCard.module.css
index b494e9d7ec..5342b634a7 100644
--- a/design-system/packages/ui/src/flow-chat/tool-cards/FlowChatToolCard.module.css
+++ b/design-system/packages/ui/src/flow-chat/tool-cards/FlowChatToolCard.module.css
@@ -2,7 +2,7 @@
.prominentRoot,
.ambientRoot {
--_tool-card-action-size: var(--bf-space-6);
- --_icon-size: var(--bf-font-size-xl);
+ --_flow-chat-tool-card-icon-size: var(--bf-font-size-xl);
--_tool-card-transition: var(--bf-motion-duration-fast) var(--bf-motion-easing-standard);
box-sizing: border-box;
@@ -261,8 +261,8 @@
.iconMarks {
position: relative;
display: inline-flex;
- inline-size: var(--_icon-size);
- block-size: var(--_icon-size);
+ inline-size: var(--_flow-chat-tool-card-icon-size);
+ block-size: var(--_flow-chat-tool-card-icon-size);
align-items: center;
justify-content: center;
}
diff --git a/design-system/packages/ui/src/primitives/Stack/Stack.tsx b/design-system/packages/ui/src/primitives/Stack/Stack.tsx
index 41dbf0032c..e6bb5d7003 100644
--- a/design-system/packages/ui/src/primitives/Stack/Stack.tsx
+++ b/design-system/packages/ui/src/primitives/Stack/Stack.tsx
@@ -4,6 +4,19 @@ import styles from "./Stack.module.css";
type StackGap = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "12";
+const stackGapVariables = {
+ "0": "var(--bf-space-0)",
+ "1": "var(--bf-space-1)",
+ "2": "var(--bf-space-2)",
+ "3": "var(--bf-space-3)",
+ "4": "var(--bf-space-4)",
+ "5": "var(--bf-space-5)",
+ "6": "var(--bf-space-6)",
+ "8": "var(--bf-space-8)",
+ "10": "var(--bf-space-10)",
+ "12": "var(--bf-space-12)",
+} as const satisfies Record
;
+
export interface StackProps extends HTMLAttributes {
align?: "start" | "center" | "end" | "stretch";
direction?: "horizontal" | "vertical";
@@ -24,7 +37,7 @@ export function Stack({
}: StackProps) {
const stackStyle = {
...style,
- "--_stack-gap": `var(--bf-space-${gap})`,
+ "--_stack-gap": stackGapVariables[gap],
} as CSSProperties;
return (
diff --git a/design-system/packages/ui/tests/icon.test.mjs b/design-system/packages/ui/tests/icon.test.mjs
index 215b964095..544338d654 100644
--- a/design-system/packages/ui/tests/icon.test.mjs
+++ b/design-system/packages/ui/tests/icon.test.mjs
@@ -1,7 +1,7 @@
import assert from "node:assert/strict";
import { createElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
-import { readFile } from "node:fs/promises";
+import { readFile, readdir } from "node:fs/promises";
import test from "node:test";
import { Icon, iconNames } from "../dist/index.js";
@@ -50,3 +50,19 @@ test("Icon styles consume only public geometry and semantic color tokens", async
assert.match(styles, /--bf-color-status-success-content/);
assert.match(styles, /mask-size:contain/);
});
+
+test("Icon mask assets are color-agnostic", async () => {
+ const assetDirectory = new URL("../src/components/Icon/assets/", import.meta.url);
+ const assetNames = (await readdir(assetDirectory)).filter((name) => name.endsWith(".svg"));
+
+ assert.equal(assetNames.length, iconNames.length);
+ for (const assetName of assetNames) {
+ const source = await readFile(new URL(assetName, assetDirectory), "utf8");
+ assert.match(source, /(?:fill|stroke)="currentColor"/i, `${assetName} must use currentColor`);
+ assert.doesNotMatch(
+ source,
+ /\b(?:fill|stroke)="(?:black|white|#[0-9a-f]{3,8}|rgba?\()/i,
+ `${assetName} must not own a color`,
+ );
+ }
+});
diff --git a/docs/architecture/theme-token-optimization.md b/docs/architecture/theme-token-optimization.md
index d24adce6af..987a73128e 100644
--- a/docs/architecture/theme-token-optimization.md
+++ b/docs/architecture/theme-token-optimization.md
@@ -1,181 +1,308 @@
# 主题与颜色 Token 治理
-本文定义 BitFun 各界面的主题所有权、Token 分层、生成边界和防回退规则。它只保留长期有效的架构约束,
-不记录审计数量、迁移批次或阶段历史。当前事实以以下可执行契约及其输出为准:
+本文定义 BitFun 全部前端的颜色所有权、运行时投影和防回退契约。目标不是在旧变量之上再包一层,
+而是让设计系统成为普通 UI 颜色的唯一公共来源:组件只消费 canonical `--bf-*`,产品层只选择、
+组合和投影这些 Token,不再维护第二套别名体系。
+当前事实以以下可执行契约及其输出为准:
+
+- `design-system/packages/design-tokens`
+- `design-system/packages/theme-bitfun`
+- `src/web-ui/src/infrastructure/appearance/appearanceTokenContract.ts`
- `scripts/theme-color-governance-baseline*.json`
- `scripts/theme-color-near-pair-decisions.json`
- `scripts/theme-css-var-contract.mjs`
- `scripts/theme-visual-governance-contract.json`
-- `scripts/audit-theme-colors.mjs` 与 `scripts/audit-cli-theme-colors.mjs`
+- `scripts/frontend-color-surface-registry.json`
+- `scripts/audit-frontend-colors.mjs`
+- `scripts/audit-theme-colors.mjs`
-文档与可执行契约冲突时,先核对代码和审计脚本;不得通过修改文档掩盖实际回退。
+文档与代码或审计结果冲突时,应修复 owner、消费方或契约;不得通过提高 baseline、扩充宽泛 allowlist
+或恢复旧变量来掩盖回退。
-## 范围
+## 一条正向依赖链
-本治理覆盖:
+| 层级 | 唯一职责 | 不拥有的内容 |
+|---|---|---|
+| `@bitfun/design-tokens` | 主题无关的命名、系统尺度和基础 Token 契约 | BitFun 具体 light/dark 值、产品状态、route 或运行时选择 |
+| `@bitfun/theme-bitfun` | BitFun 的 reference/semantic 主题值、canonical CSS 变量映射和 `default.css` | Web UI Appearance 包、产品 store、组件内部状态 |
+| `@bitfun/ui` | 消费 semantic/system Token 的公共组件 anatomy、行为和无障碍契约 | 具体主题值、Appearance schema、旧 Web UI 变量 |
+| Web UI Appearance | 选择和组合主题,生成 schema v2 包,并投影 canonical root/scoped Token 与显式 product domain/component Token | 公共 Token 的第二套命名、兼容双写、组件私有 palette |
+| 产品前端 | 选择主题、设置设计系统 root 属性并消费 canonical Token | 复制 `theme-bitfun` palette、随组件新增 raw color |
-- `design-system` 的共享系统 Token、BitFun 默认语义主题和独立组件消费契约。
-- `src/web-ui` 的 Appearance 包、CSS 变量投影、组件样式和专用渲染色板。
-- `src/mobile-web` 的移动端主题与运行时变量。
-- `BitFun-Installer/src` 的安装器主题、首屏静态变量和流程组件。
-- `src/apps/cli` 的 TUI preset、终端颜色映射和降级行为。
-- Desktop 首屏 bootstrap、生成式 UI 主题提示等由主题源生成的只读产物。
-- BitFun GUI 插件的语义色投影,以及 OpenCode TUI 主题的独立兼容边界。
+正向依赖固定为:
-本治理不要求不同产品形态共享完整主题 schema,也不把 Monaco、终端 ANSI、Mermaid、语法高亮、diff、
-语言标识或数据可视化色板强行合并为普通应用 Token。
+```mermaid
+flowchart LR
+ System["@bitfun/design-tokens
命名与系统尺度"] --> Theme["@bitfun/theme-bitfun
默认语义值"]
+ System --> UI["@bitfun/ui"]
+ Theme --> UI
+ Theme --> Appearance["Web UI Appearance v2
产品主题组合"]
+ Appearance --> Runtime["theme-tokens adapter"]
+ Runtime --> Root["canonical root --bf-*"]
+ Runtime --> Scope["canonical scoped --bf-*"]
+ Theme --> Surfaces["Web surfaces / Desktop bootstrap / MiniApp projection"]
+ Mobile["Native mobile contract"] --> Native["HarmonyOS / Android / iOS"]
+```
-## 所有权与依赖方向
+这里没有 compatibility projection。共享设计系统包不能反向依赖 Web UI Appearance;组件、生成产物、
+Desktop bootstrap 和产品前端也不能反向定义公共主题值。
-| 范围 | 权威 owner | 消费或产物路径 | 约束 |
-|---|---|---|---|
-| 共享设计系统 Token | `design-system/packages/design-tokens` 与 `design-system/packages/theme-bitfun` | `@bitfun/ui`、Design Lab、Web UI 的 canonical CSS 变量 | 前者拥有主题无关名称和系统尺度,后者拥有可替换的 BitFun 默认语义值;不得依赖产品 route、store、locale、Tauri 或专用渲染域 |
-| Web UI Appearance | `src/web-ui/src/infrastructure/appearance` | 运行时 CSS、组件/Scene 契约与 renderer adapter | 拥有包 schema、运行时选择、导入导出、历史包兼容、产品/component Token 和专用域投影;默认 light/dark 共享值从 `@bitfun/theme-bitfun` 取得,Rust 不复制 |
-| Desktop 首屏 | Web UI builtin Appearance 与 `scripts/generate-startup-appearance-bootstrap.mjs` | `src/apps/desktop/src/generated/startup_appearance_bootstrap.json` | 只保存 JS 加载前必要字段;生成产物不能反向定义 Appearance |
-| 生成式 UI 提示 | Web UI builtin Appearance 与 `scripts/generate-startup-appearance-bootstrap.mjs` | `src/crates/assembly/core/src/agentic/tools/implementations/generated/appearance_prompt_snapshots.json` | 只读生成产物;Rust 不手写第二套内置 palette |
-| Mobile Web | `src/mobile-web/src/theme` | Mobile 运行时变量与组件 | 不从 Desktop 或 Web UI 运行时偷读内部变量 |
-| Installer | `BitFun-Installer/src/theme` | `BitFun-Installer/src/styles/variables.css` 与流程组件 | Rust 壳不复制完整 palette |
-| CLI/TUI | `src/apps/cli/themes/presets` 与 `src/apps/cli/src/ui/theme.rs` | 终端样式 | 拥有 preset、ANSI/monochrome 降级;不实现 Web `ThemeConfig` |
-| BitFun GUI 插件 | Web UI Appearance owner | `src/web-ui/src/infrastructure/appearance/adapters/PluginAppearanceProjection.ts` | 只投影约定的语义色,不暴露包或内部变量全集 |
-| OpenCode TUI 主题 | CLI/TUI 兼容适配器 | OpenCode 主题来源与终端投影 | 保留来源顺序、稳定字段、引用和 light/dark 变体;不由 GUI 七色投影替代 |
-| 专用渲染域 | 对应 editor、terminal、syntax、diff、Mermaid 等模块 | 各自 namespace | 不得泄漏为普通组件随手可用的色板 |
+## Canonical Token 分层
-依赖方向固定为:
+正向代码只使用以下四类 Token:
-```mermaid
-flowchart LR
- System["@bitfun/design-tokens
共享名称与系统尺度"] --> Theme["@bitfun/theme-bitfun
BitFun 默认语义值"]
- System --> Components["@bitfun/ui"]
- Theme --> Source["Web UI builtin Appearance
产品与专用域组合"]
- Source --> Runtime["AppearanceRuntime"]
- Source --> Generator["Appearance 生成器"]
- Generator --> Bootstrap["Desktop 首屏 bootstrap"]
- Generator --> Prompt["生成式 UI 提示快照"]
- Runtime --> Canonical["canonical --bf-* 投影"]
- Runtime --> Compatibility["兼容 --bf-appearance-token-*"]
- Runtime --> Projection["GUI 插件语义色投影"]
+1. **System / semantic**:`--bf-color-*`、`--bf-shadow-*`、`--bf-effect-*`、`--bf-opacity-*`
+ 等由设计系统发布的公共变量,是普通 UI 的默认消费层。
+2. **Component**:`--bf-component-*`。仅用于跨消费方稳定存在、又无法由 semantic Token 准确表达的
+ 组件差异;必须在 `appearanceTokenContract.ts` 中登记。
+3. **Product domain**:`--bf-domain-*`。用于 Git lane、语言身份、syntax、inspector、工具类别等明确的
+ 专用语义;不得当作普通 UI 的备用色板。
+4. **Renderer payload**:Monaco、xterm、Mermaid、BitFun Canvas 等第三方或专用渲染器的显式配置。
+ 它们有各自格式,不进入普通组件 CSS。
+
+Primitive/reference 色值只存在于主题 authoring、明确的主题 preset 或专用 renderer owner 中。普通组件
+不得直接消费 reference ramp,也不得自行定义“看起来差不多”的局部颜色。
+
+新增颜色按以下顺序判断:
+
+1. 语义相同,直接复用现有 semantic Token。
+2. 数值相近且相邻状态仍可区分,合并到已有 Token,并更新 near-pair 决策。
+3. 存在独立、稳定、可说明的组件语义,在最窄 owner 中新增 `--bf-component-*`。
+4. 属于产品或渲染专用域,进入 `--bf-domain-*` 或 renderer payload。
+5. 只有主题本身需要新的基础色时,才修改 `@bitfun/theme-bitfun` 的 authoring source。
+
+数值接近不是唯一判断标准;相邻背景/边框、文本层级、状态色、diff、syntax 和数据系列必须结合同时
+出现时的区分度审查。反过来,也不能以“可能有视觉差异”为理由给每个组件建立近似私有颜色。
+
+## 普通 UI 的硬约束
+
+普通应用组件和页面必须满足:
+
+- 颜色、阴影和 blur 只从 canonical Token 取得;允许用 `color-mix()`、gradient 等 CSS 运算组合 Token。
+- 不写 hex、rgb、hsl、命名色等 raw color;静态资产元数据和明确主题/renderer owner 除外。
+- 不使用 `var(--token, fallback)` 隐藏缺失 Token。
+- 不引用未定义、未登记或跨 root 偷借的变量。
+- 不定义 `--color-*`、`--lab-*` 或 `--bf-appearance-token-*` 等局部/历史公共前缀。
+- SVG 图标优先使用 `currentColor`,由外层 semantic Token 控制状态。
+- Component-private 非颜色变量可使用包约定的 `--_` 前缀,但不能借此建立私有颜色系统。
+
+静态 favicon、manifest、SVG metadata 等不参与组件主题切换的值只能计入 `assetMetadata`。它们不能迁回
+`appUi` allowlist,也不能被组件引用。
+
+## Web UI Appearance schema v2
+
+Web UI Appearance 的当前 schema 固定为 v2。颜色入口是 `theme-tokens` renderer:
+
+```ts
+{
+ "theme-tokens": {
+ version: 1,
+ settings: {
+ tokens: { "--bf-color-*": "...", "--bf-component-*": "...", "--bf-domain-*": "..." },
+ scopes: {
+ chrome: { "--bf-color-*": "..." }
+ }
+ }
+ }
+}
```
-共享设计系统包不能反向依赖 Appearance;生成产物、Rust bootstrap、插件投影和消费组件也不能反向定义
-Appearance。Desktop 和 Web UI 只持久化并解析 `appearance.selection`。旧 `theme`、`themes` 和 Skin 数据
-不兼容、不迁移。
+其边界如下:
-## Token 分层
+- `tokens` 只能包含 `appearanceTokenContract.ts` 登记的 root Token。
+- `scopes.chrome` 只能重绑定设计系统已有的 canonical theme Token,并应用到
+ `[data-bf-theme-scope="chrome"]`;scope 内不发明另一套 chrome 名称。
+- `ThemeTokenAppearanceAdapter` 在切换时移除上一包写入的 root/scoped Token,再写入新包;不双写任何
+ 历史名称。
+- Token 名和 Token 值都经过 allowlist 与安全校验;未登记名称、嵌套 `var()`、URL 或可注入片段直接失败。
+- builtin Appearance 从 `@bitfun/theme-bitfun` 的完整主题值开始,只覆盖产品 theme/preset 真正不同的
+ canonical 值,再补充受治理的 component/domain Token。
+- Widget、Desktop 首屏 bootstrap 和生成式 UI 提示只消费同一 canonical 源生成的 allowlist 产物,
+ 不能反向成为主题 owner。
-Token 只按职责分四层:
+`CssTokenAppearanceAdapter`、`appearanceTokenProjection`、`css-tokens` renderer 和
+`--bf-appearance-token-*` 运行时变量均已退休。不得为第三方包、旧组件或测试重新引入这些接口。
-1. **Primitive**:颜色原料和必要 alpha ramp,不表达业务含义。
-2. **Semantic**:背景、文本、边框、交互、状态和产品意图,是普通组件的默认消费层。
-3. **Component**:仅在稳定组件契约无法由 semantic token 清楚表达时增加。
-4. **Exception domain**:editor、terminal、syntax、diff、Mermaid、语言标识和其他专用色板。
+### v1 读取不是兼容运行时
-兼容别名不是第五层。它只服务已确认的迁移调用方,必须声明 canonical 目标、owner 和移除条件;新代码不得继续
-读取历史别名。
+升级兼容只存在于包读取入口:
-应用结构层可以使用 `--bf-appearance-token-chrome-*` 这一窄化的 component token 家族,表达导航、标签栏和
-工作台外壳相对于内容面的稳定反相关系。它由 Web UI builtin Appearance 投影拥有,只能在结构层 scope 内重绑定
-普通 semantic token;未声明独立 chrome palette 的内置或导入外观沿用所属 light/dark 基础外观的内容色,不能让
-组件按 Appearance ID 硬编码颜色特例。
+1. Parser 识别持久化的 schema v1 包。
+2. `migrateAppearancePackage` 将已知 `css-tokens` 字段和旧名称单向映射为 v2 `theme-tokens` root/scoped
+ canonical Token。
+3. 旧 `css-tokens` renderer 被删除,后续校验、运行时和导出只接收 v2。
+4. 已安装的旧包在加载后重新保存为 v2,之后不再依赖旧名称。
-共享设置页可以使用 `--bf-appearance-token-config-page-*` 这一窄化的 component token 家族,分别表达 section
-块面、section 边界、行分隔线与 hover 填充。它只由 `ConfigPageLayout` 消费,默认映射回普通 element/border
-semantic token;仅当某个 Appearance 需要让“信息块面”和“表单控件边界”采用不同层级时才覆写,不能扩散成
-通用卡片色板或按 Appearance ID 编写 CSS 特例。
+因此,旧名称只允许出现在迁移映射、upgrade fixture 和“不得出现”的负向断言中。它们不是可供新代码
+消费的 alias,也不会在 DOM 中生成。未知旧字段不得被猜测或静默投影;应保留原数据并给出明确的不支持状态。
-新增颜色按以下顺序判断:
+## 全前端 Surface 注册表
-1. 语义相同:复用现有 Token。
-2. 色值近似且相邻状态不会失去区分:合并并更新审计决策。
-3. 存在独立、稳定且可说明的用户语义:在最窄 owner 中新增 semantic 或 component token。
-4. 属于专用渲染域:进入对应 exception namespace,不扩张普通应用色板。
+`scripts/frontend-color-surface-registry.json` 是前端颜色治理范围的唯一清单。每个可交付或可运行的前端必须
+登记稳定 `id`、源码 root、颜色 owner 和审计引擎;新增目录不能依赖维护者再给 `package.json` 手写一段命令。
+当前注册表覆盖:
-不得仅因数值接近就合并颜色。相邻背景/边框、文本层级、成功/警告/错误、diff、语法和数据系列必须结合实际
-同时出现的状态复核。反过来,也不能用“可能有视觉差异”作为每个组件新增近似色的理由。
+- Web UI、`@bitfun/ui`、Design Lab、Website、Mini App Market、Skin Market、Mobile Web 和 Installer。
+- Desktop JavaScript 启动前页面、Native Mobile 比较预览、CLI/TUI。
+- HarmonyOS、Android、iOS 三端原生源码。
+- 全部 builtin/Demo MiniApp 及其内置 Skill reference mirror。
+- `@bitfun/design-tokens` 与 `@bitfun/theme-bitfun` 的 authoring owner。
-## CSS 变量与运行时边界
+`scripts/audit-frontend-colors.mjs` 只从该注册表编排检查:普通 Web surface 复用 CSS/Token 审计,CLI 复用终端
+主题审计,Native Mobile 与 MiniApp 使用各自的源码契约检查。MiniApp discovery 会从三个登记的父目录查找
+所有带 `meta.json` 的应用;发现未登记应用、登记路径消失或 reference mirror 不再 byte-equal 都直接失败。
-- 新设计系统组件只消费包生成的 canonical `--bf-*` 变量。`--bf-appearance-token-*` 仍是现有 Appearance
- 包和产品代码的兼容输入,不是新公共组件 API。
-- `CssTokenAppearanceAdapter` 在同一次原子应用中写入历史变量,并通过显式 allowlist 把共享部分投影到
- canonical 变量。投影表由产品基础设施拥有,不能移入 `@bitfun/ui` 或让独立包识别 Appearance schema。
-- 普通组件优先消费运行时 CSS 变量;不得用 SCSS 编译期颜色复制动态主题语义。
-- `tokens.scss` 可以保留尺寸、字体、动效、root Token 和少量兼容 mixin,不应成为第二套产品颜色源。
-- 动态 CSS 变量族必须在 `theme-css-var-contract.mjs` 登记 owner、前缀和消费范围。
-- fallback 只允许存在于明确的启动、第三方或兼容边界;普通组件不得用 fallback 隐藏缺失 Token。
-- 未解析变量、未登记 key、跨 root 借用和运行时/静态定义漂移必须由审计失败暴露。
-- iframe、MiniApp 或生成式 UI 只接收显式 allowlist 的主题 payload,不接收 Web UI 内部变量全集。
-- 导入 Appearance 由 Web UI 加载和校验。Rust 首屏无法解析导入包时使用系统默认启动色,JS 启动后再原子应用完整包。
+注册表不是兼容表。surface 被下线时删除条目,owner 被迁移时原子更新唯一条目;不得同时登记新旧 root、双写
+变量或用另一个命令继续扫描退休实现。
-## 防回退契约
+## 各前端 surface 的 owner
-主题 baseline 是 no-growth ratchet,不是普通快照。审计失败时,默认修复方式是复用 Token、删除游离 key、收敛
-近似色、修复 owner 或补最小契约,不能直接提高 baseline、扩充 allowlist、放宽测试或关闭检查。
+### Design Lab、Website、Market
-baseline 只允许两类变更:
+Design Lab、Website、Mini App Market 与 Skin Market 直接加载 `@bitfun/theme-bitfun/default.css`,通过
+`data-bf-design-system-root`、`data-color-scheme`、`data-contrast` 和 `data-density` 选择已发布主题。
+它们可以拥有布局和产品交互,但不得再维护本地 light/dark palette。
-- 实际债务下降时同步下调。
-- 确有新的用户语义且无法复用时,在独立治理变更中说明 owner、消费方、相邻状态、无障碍影响、回退方式和复审结论。
+### Mobile Web / Remote Control
-治理不预设脱离代码检查的固定 Token 数量。预算由审计维度、现有 baseline 和真实消费关系共同约束;没有 checker
-保护的任意数字会快速失真,不应成为架构承诺。
+Mobile Web 直接消费 `@bitfun/theme-bitfun`。`ThemeProvider` 与首屏 bootstrap 只负责选择 light/dark、
+写设计系统 root 属性和同步浏览器 `theme-color`;已退休的本地 preset/ramp 不得恢复。Relay 中的 Mobile
+静态包必须由这一源码重新构建,不能保留旧 Vite 产物作为隐式第二套主题实现。
-以下做法视为治理回退:
+### Desktop bootstrap 与 Native Mobile 预览
-- 为通过 CI 上调 baseline 或 fixture 期望。
-- 把普通组件路径加入专用域 allowlist。
-- 新增与现有 Token 等价的字面量或 fallback。
-- 在 Rust、CLI 或安装器中复制 Web UI 的完整主题模型。
-- 用生成文件或产品定制配置绕过主题 owner。
+Desktop 的更新确认页和启动页只消费 `src/apps/desktop/src/generated/bootstrap_theme.css` 发布的 canonical
+`--bf-*`,不得内联另一套启动色。该 CSS 和两个 Appearance manifest 一起由
+`generate-startup-appearance-bootstrap.mjs` 从正式主题/Appearance 源生成;统一颜色审计执行 `--check`,
+生成物漂移直接失败。
+
+Native Mobile 预览的工具 chrome 消费 canonical `--bf-*`;设备画布消费 `--mobile-*` 这一受登记的 scoped
+动态变量族,其值只来自生成的 mobile contract data。二者不互相 alias。预览不得直接解释 ARGB 字符串为 Web
+颜色,必须在投影边界显式转换;generated data 不作为普通 UI 源码重复计数,但必须通过生成物漂移检查。
+
+### HarmonyOS / Android / iOS
+
+原生移动端不加载 Web CSS,也不复制 `@bitfun/theme-bitfun`。它们的唯一跨平台视觉事实 owner 是
+`src/apps/mobile/design-system/tokens/mobile-tokens.json`:
+
+- 颜色名称按语义登记,例如 content、surface、status、scrim、media control 和 shadow;不得使用 `green`、
+ `red`、`white` 之类数值或外观名称充当公共 API。
+- `mobile-ui-design-system.mjs` 从同一 contract 生成 ArkTS/Kotlin/Swift 常量与预览数据;组件契约引用不存在的
+ token 或任一生成物漂移都会失败。
+- 三端非 generated 源码不得出现 `Color.White` / `.black` / `.clear`、颜色构造器、hex 字符串或同类平台
+ raw color。system bar 等平台桥接读取生成的 light/dark pair,不在 entrypoint 重建 palette。
+- Android vector、iOS asset catalog 与 HarmonyOS template media 是可 tint 的平台资产 owner,不是普通 UI
+ 颜色来源;渲染时仍必须由 semantic token 控制。
+
+### Installer
-## 产品定制与扩展
+Installer 首屏和普通流程组件加载设计系统默认主题并只消费 canonical Token。主题选择器保留六个明确的
+自定义安装器 preset;这些 preset 的身份色是唯一允许的 installer raw-color owner,并由 Installer 专属
+baseline 约束。运行时只把选中 preset 投影到 canonical `--bf-color-*` 子集。
-产品定制只引用宿主已注册的 Appearance ID,或对应边界明确允许的少量语义色;不得携带任意 CSS、完整
-Appearance 包、renderer 配置、动态代码或源码替换。详细边界见
-[`product-customization-blueprint.md`](product-customization-blueprint.md)。
+Installer 不再拥有 `src/styles/variables.css`,也不得让页面直接读取 preset 对象或建立页面级变量。新增
+preset 必须同时说明用户可见差异、相邻状态对比、所需 canonical 投影和 baseline 变化,不能借新增 preset
+扩大普通 UI 的 raw-color 预算。
-GUI、Mobile、Installer 和 CLI/TUI 可以选择不同主题集合,但共享规则而不是共享全部数据结构:
+### MiniApp 公共投影
-- 身份与品牌配置选择已注册 ID。
-- 每个 surface 的 owner 校验该 ID 和能力范围。
-- 未支持的组合在构建期或入口启动时失败,不静默回默认造成品牌错配。
-- OpenCode TUI 主题保持独立格式;BitFun GUI 插件七色投影不构成 OpenCode 兼容承诺。
+MiniApp 不能读取 Web UI 内部变量全集。公开边界只有 `src/shared/miniapp-appearance/contract.json` 中登记的
+`--bitfun-*`,每一项都投影自 `@bitfun/design-tokens` 或 `@bitfun/theme-bitfun` 的真实 canonical 变量。
+Web UI payload、Rust 首帧 style 和 MiniApp 源码共同遵守以下约束:
-## 变更流程
+- 使用未登记的 `--bitfun-*`、在应用内重新定义宿主变量、或写 `var(--bitfun-*, fallback)` 均直接失败。
+- `default_appearance_style.html` 由公共 contract 生成,不是第三个 palette owner。
+- Demo/builtin 与内置 Skill 中的 reference mirror 必须 byte-equal;修改正式样例时同时更新 mirror,不保留旧版。
+- 普通 MiniApp chrome 的 raw color 为零。专用色不进入通用 baseline,只能登记到下表的最窄 owner;owner
+ 条目没有真实 occurrence 时也会因 stale 而失败。
-1. 确认变更所属 surface、主题 owner、用户语义和相邻视觉状态。
-2. 优先复用现有 semantic token;新增 Token 时选择最窄层级和 namespace。
-3. 共享名称或默认 BitFun 值更新对应 design-system owner;运行时、导入兼容或产品/专用域更新 Web UI
- Appearance owner、校验器、compiler、投影和真实消费方。
-4. 仅在 JS 加载前确有需要时重新生成 Desktop bootstrap;生成式 UI 提示按同一 Appearance 源更新。
-5. 涉及动态变量、别名、专用域或跨 root 时,同步更新对应可执行 contract。
-6. 运行自动检查,并对受影响 surface、light/dark/system、交互状态和无障碍对比做 focused review。
+| MiniApp | 允许的专用 owner | 边界 |
+|---|---|---|
+| Coding Selfie | `data-viz` | `LANG_COLORS` 语言数据系列块 |
+| Git Graph | `data-viz` | branch lane 5–7 的三个分类色;其余 lane 使用宿主语义 |
+| Gomoku | `game-renderer` | 黑白棋子填充与对比描边变量 |
+| Daily Divination | `bespoke-theme` | 塔罗场景本身的完整插画 light/dark 主题 |
+| PPT Live | `slide-renderer` | 幻灯片内容、导出器和 renderer fixture;编辑器 chrome 仍为零 raw color |
+| Regex Playground / Icon Design System | 无 | 全部视觉消费宿主投影 |
-主题变更至少运行:
+### 专用 renderer 和资产
+
+Monaco、xterm/ANSI、Mermaid、syntax、diff、语言标识、调试 overlay、Canvas 和数据系列有独立的格式或
+稳定语义。它们必须留在对应 renderer/domain owner 中,并通过明确 payload 或 `--bf-domain-*` 消费;不得
+泄漏成普通组件可随手调用的 palette。
+
+### 显式排除不是 allowlist
+
+Monaco 拷贝产物、Relay static、E2E fixture、诊断报表 HTML、PPT 内容 renderer、native template icons 和
+generated outputs 不属于普通应用 UI 扫描。每个边界都必须在 surface registry 中用现存路径、唯一 owner、
+artifact kind 和具体理由登记;路径消失或只写模糊理由会使 registry contract test 失败。
+
+这些条目不会允许同名颜色进入其他目录,也不能用 glob 把普通组件一起隐藏。PPT、native asset 等专用 owner
+仍由各自的 renderer、生成器或平台 tint 契约验证;“不计入普通 UI raw color”不等于“不受治理”。
+
+## 防回退契约
+
+主题 baseline 是 no-growth ratchet,不是可随实现调整的快照。以下指标对普通 UI 均应保持为零:
+
+- raw color occurrences / unique colors
+- fallback occurrences / unique tokens
+- unresolved required variables
+- compatibility alias usage
+- unregistered dynamic families
+- indistinguishable near pairs
+- non-canonical Widget payload fields
+
+审计失败时,默认修复方式是复用 Token、删除游离 key、收敛近似色、修复 owner 或补最小 component/domain
+契约。以下做法均视为治理回退:
+
+- 为通过 CI 上调 baseline 或 fixture 期望。
+- 把普通组件路径加入 renderer/asset exception allowlist。
+- 新增与现有 Token 等价的字面量、fallback 或 alias。
+- 在 Mobile、Installer、Website、Market、Rust 或生成产物中复制公共 palette。
+- 同时写 canonical 与旧变量,或保留两个 adapter 让调用方任选。
+- 用生成文件、产品定制或静态 Vite 产物绕过当前主题 owner。
+
+baseline 只允许两类变更:实际债务下降时同步下调;或确有新的稳定语义时,在独立治理变更中给出 owner、
+真实消费方、相邻状态、无障碍影响和复审结论。
+
+## 变更与验证
+
+颜色变更应按 owner 完成,而不是逐页面补丁:
+
+1. 确认 surface、用户语义、相邻状态和唯一 owner。
+2. 优先复用现有 semantic Token;确需新增时选择最窄 component/domain/renderer 边界。
+3. 更新 authoring source、运行时 contract 和真实消费方;删除被替代的旧 API、文件和变量。
+4. 若影响首屏、Widget 或静态包,从 canonical 源重新生成/构建产物。
+5. 运行最窄 owner 测试,再运行跨 surface 颜色审计。
+
+核心自动门禁为:
```bash
+pnpm run theme:color-audit:test
+pnpm run theme:color-audit:all
+pnpm run theme:color-audit:miniapps
+pnpm run theme:color-audit:native-mobile
+pnpm run theme:visual-contract
+pnpm run appearance:contract-audit
+pnpm run design-system:check
pnpm run check:web
-pnpm run generate-startup-appearance-bootstrap
```
-`check:web` 聚合执行类型检查、Appearance contract、主题颜色审计及其 contract tests,以及主题视觉治理契约,
-与 CI 针对 Web UI 的 Appearance 门禁保持一致。
-
-若 Appearance 源影响生成产物,先运行 `pnpm run generate-startup-appearance-bootstrap`,再确认只有预期的只读产物发生变化。
-跨 surface 视觉变化还应按 `theme-visual-governance-contract.json` 的覆盖项完成 focused review;自动审计不等于视觉
-或对比度已经通过。
+另外还应执行被改动 surface 的 type-check/test/build。自动审计、source 检查和 build 只能证明契约与产物
+一致,不能替代真实渲染的视觉与对比度审查;设计验收应在 Design Lab 或真实产品中人工完成,不能把浏览器
+自动化截图或 Mock 当作最终视觉证据。
-## 当前判定
+## 完成判据
-普通应用组件的 raw color、等价字面量、fallback 和近似色债务由审计脚本与 baseline 持续守护;本文不复制某次
-扫描数量。专用渲染 palette、兼容别名和各产品形态的独立主题仍然存在,它们只有在缺少 owner、越过作用域或
-重新进入普通组件时才构成债务。
+颜色体系只有在以下条件同时满足时才算完成:
-主题治理完成的判据不是“色值最少”,而是:
+- 普通 UI 的每个颜色都能追溯到一个 canonical semantic/component Token。
+- 每个专用色值都能追溯到一个 theme preset、domain、renderer 或 asset metadata owner。
+- Web UI 运行时只投影 schema v2 `theme-tokens`,DOM 中没有历史变量。
+- Mobile、Website、Market、Installer 和 Design Lab 不复制公共 palette。
+- v1 只在读取时迁移,正向源码、样式、产物与导出中不存在旧名称。
+- baseline 默认只下降,新增语义必须有真实消费方和明确审查证据。
-- 每个普通组件颜色都能追溯到稳定语义 Token。
-- 每个专用色板都有清楚 owner 和边界。
-- 每层主题事实只有一个权威 owner:共享名称与默认值属于 design-system,运行时选择与产品/专用域组合属于
- Appearance;生成物不反向定义契约。
-- 新主题和产品定制不需要复制 Rust/React/TUI 实现。
-- 审计 baseline 默认只下降;确需合理增长时,必须经独立评审且有真实消费方。
+完成目标不是“色值数量最少”,而是每个颜色只有一个权威 owner、每个消费方只依赖稳定语义、每次回退都能
+被自动门禁准确阻断。
diff --git a/package.json b/package.json
index 48ecc49c26..86e7b28a27 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,8 @@
"generate-version": "node scripts/generate-version.cjs --build-env production",
"generate-version:dev": "node scripts/generate-version.cjs --build-env development",
"generate-startup-appearance-bootstrap": "node scripts/generate-startup-appearance-bootstrap.mjs",
+ "miniapp:appearance:generate": "node scripts/generate-miniapp-appearance-contract.mjs",
+ "miniapp:appearance:check": "node scripts/generate-miniapp-appearance-contract.mjs --check",
"generate-all": "pnpm run generate-version && pnpm run generate-startup-appearance-bootstrap",
"postinstall": "pnpm run copy-assets",
"dev": "node scripts/dev.cjs web",
@@ -39,12 +41,21 @@
"iconography:check": "node scripts/iconography/generate.mjs --check",
"typography:audit": "node scripts/audit-typography-tokens.mjs",
"typography:audit:test": "node --test scripts/audit-typography-tokens.test.mjs",
- "theme:color-audit": "node scripts/audit-theme-colors.mjs",
- "theme:color-audit:mobile": "node scripts/audit-theme-colors.mjs --root src/mobile-web/src --baseline scripts/theme-color-governance-baseline.mobile-web.json",
- "theme:color-audit:installer": "node scripts/audit-theme-colors.mjs --root BitFun-Installer/src --baseline scripts/theme-color-governance-baseline.installer.json",
- "theme:color-audit:cli": "node scripts/audit-cli-theme-colors.mjs",
- "theme:color-audit:all": "pnpm run theme:color-audit && pnpm run theme:color-audit:mobile && pnpm run theme:color-audit:installer && pnpm run theme:color-audit:cli",
- "theme:color-audit:test": "node --test scripts/audit-theme-colors.test.mjs scripts/audit-cli-theme-colors.test.mjs",
+ "theme:color-audit": "node scripts/audit-frontend-colors.mjs --surface web-ui",
+ "theme:color-audit:design-lab": "node scripts/audit-frontend-colors.mjs --surface design-lab",
+ "theme:color-audit:design-system-ui": "node scripts/audit-frontend-colors.mjs --surface design-system-ui",
+ "theme:color-audit:miniapp-market": "node scripts/audit-frontend-colors.mjs --surface miniapp-market",
+ "theme:color-audit:skin-market": "node scripts/audit-frontend-colors.mjs --surface skin-market",
+ "theme:color-audit:website": "node scripts/audit-frontend-colors.mjs --surface website",
+ "theme:color-audit:mobile": "node scripts/audit-frontend-colors.mjs --surface mobile-web",
+ "theme:color-audit:installer": "node scripts/audit-frontend-colors.mjs --surface installer",
+ "theme:color-audit:cli": "node scripts/audit-frontend-colors.mjs --surface cli",
+ "theme:color-audit:desktop-bootstrap": "node scripts/audit-frontend-colors.mjs --surface desktop-bootstrap",
+ "theme:color-audit:mobile-preview": "node scripts/audit-frontend-colors.mjs --surface mobile-design-preview",
+ "theme:color-audit:native-mobile": "node scripts/audit-frontend-colors.mjs --kind native-mobile",
+ "theme:color-audit:miniapps": "node scripts/audit-frontend-colors.mjs --kind miniapp",
+ "theme:color-audit:all": "node scripts/audit-frontend-colors.mjs",
+ "theme:color-audit:test": "node --test scripts/audit-theme-colors.test.mjs scripts/audit-cli-theme-colors.test.mjs scripts/audit-frontend-colors.test.mjs",
"motion:audit": "node scripts/audit-web-motion.mjs",
"theme:visual-contract": "node scripts/validate-theme-visual-contract.mjs",
"appearance:contract-audit": "node scripts/audit-appearance-contracts.mjs",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3ccb0d8ea1..f89834c77f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -56,6 +56,9 @@ importers:
BitFun-Installer:
dependencies:
+ '@bitfun/theme-bitfun':
+ specifier: workspace:^
+ version: link:../design-system/packages/theme-bitfun
'@tauri-apps/api':
specifier: ^2.10.1
version: 2.10.1
@@ -207,6 +210,9 @@ importers:
src/miniapp-market-web:
dependencies:
+ '@bitfun/theme-bitfun':
+ specifier: workspace:^
+ version: link:../../design-system/packages/theme-bitfun
'@phosphor-icons/react':
specifier: ^2.1.10
version: 2.1.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -241,6 +247,9 @@ importers:
src/mobile-web:
dependencies:
+ '@bitfun/theme-bitfun':
+ specifier: workspace:^
+ version: link:../../design-system/packages/theme-bitfun
'@noble/ciphers':
specifier: ^2.1.1
version: 2.1.1
@@ -293,6 +302,9 @@ importers:
src/skin-market-web:
dependencies:
+ '@bitfun/theme-bitfun':
+ specifier: workspace:^
+ version: link:../../design-system/packages/theme-bitfun
'@phosphor-icons/react':
specifier: ^2.1.10
version: 2.1.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -587,6 +599,15 @@ importers:
specifier: ^3.0.3
version: 3.0.3(@wdio/types@8.41.0)
+ website:
+ dependencies:
+ '@bitfun/design-tokens':
+ specifier: workspace:^
+ version: link:../design-system/packages/design-tokens
+ '@bitfun/theme-bitfun':
+ specifier: workspace:^
+ version: link:../design-system/packages/theme-bitfun
+
packages:
'@antfu/install-pkg@1.1.0':
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index d1afbbbf0a..8b640e2b03 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -9,6 +9,7 @@ packages:
- "src/miniapp-market-web"
- "src/skin-market-web"
- "BitFun-Installer"
+ - "website"
- "tests/e2e"
patchedDependencies:
diff --git a/scripts/audit-appearance-contracts.mjs b/scripts/audit-appearance-contracts.mjs
index f3c4914831..072b286e7c 100644
--- a/scripts/audit-appearance-contracts.mjs
+++ b/scripts/audit-appearance-contracts.mjs
@@ -764,9 +764,9 @@ for (const [file, source] of adapterFiles) {
}
}
-const cssTokenAdapterSource = fs.readFileSync(path.join(sourceRoot, 'infrastructure', 'appearance', 'adapters', 'CssTokenAppearanceAdapter.ts'), 'utf8');
-if (!cssTokenAdapterSource.includes('APPEARANCE_CSS_TOKEN_NAMES') || cssTokenAdapterSource.includes("startsWith(ALLOWED_TOKEN_PREFIX)")) {
- failures.push('CssTokenAppearanceAdapter must validate against the closed host token registry');
+const themeTokenAdapterSource = fs.readFileSync(path.join(sourceRoot, 'infrastructure', 'appearance', 'adapters', 'ThemeTokenAppearanceAdapter.ts'), 'utf8');
+if (!themeTokenAdapterSource.includes('APPEARANCE_ROOT_TOKEN_NAMES') || themeTokenAdapterSource.includes("startsWith(ALLOWED_TOKEN_PREFIX)")) {
+ failures.push('ThemeTokenAppearanceAdapter must validate against the closed canonical token registry');
}
const widgetAdapterSource = fs.readFileSync(path.join(sourceRoot, 'infrastructure', 'appearance', 'adapters', 'WidgetAppearanceAdapter.ts'), 'utf8');
if (!widgetAdapterSource.includes('WIDGET_APPEARANCE_VARIABLE_NAMES')) {
@@ -803,7 +803,7 @@ for (const [file, source] of productionSources) {
if (/\bThemeService\b|\bthemeService\b|\buseTheme\b|\buseThemeStore\b|ThemeAppearanceBridge/.test(source)) {
failures.push(`${relative(file)}: legacy Theme runtime reference is forbidden`);
}
- if (/data-theme(?:-type)?|data-bf-theme|bitfun\/request-theme|themeChange|onThemeChange/.test(source)) {
+ if (/data-theme(?:-type)?|data-bf-theme(?!-scope(?=$|[="'\]\s]))|bitfun\/request-theme|themeChange|onThemeChange/.test(source)) {
failures.push(`${relative(file)}: legacy Theme DOM or bridge contract is forbidden`);
}
if (/--(?:color|border|element|git-color|scrollbar|shadow|blur|size|opacity|motion|easing|font|line-height|btn|flowchat|scene)-/.test(source)) {
diff --git a/scripts/audit-frontend-colors.mjs b/scripts/audit-frontend-colors.mjs
new file mode 100644
index 0000000000..971d895a18
--- /dev/null
+++ b/scripts/audit-frontend-colors.mjs
@@ -0,0 +1,845 @@
+#!/usr/bin/env node
+
+import { spawnSync } from 'node:child_process';
+import fs from 'node:fs';
+import path from 'node:path';
+import process from 'node:process';
+import { fileURLToPath } from 'node:url';
+
+const SCRIPT_PATH = fileURLToPath(import.meta.url);
+const REPOSITORY_ROOT = path.resolve(path.dirname(SCRIPT_PATH), '..');
+const DEFAULT_REGISTRY_PATH = path.join(REPOSITORY_ROOT, 'scripts/frontend-color-surface-registry.json');
+const THEME_AUDITOR_PATH = path.join(REPOSITORY_ROOT, 'scripts/audit-theme-colors.mjs');
+const CLI_AUDITOR_PATH = path.join(REPOSITORY_ROOT, 'scripts/audit-cli-theme-colors.mjs');
+const MINIAPP_SOURCE_EXTENSIONS = new Set(['.css', '.html', '.js', '.jsx', '.mjs', '.scss', '.svg', '.ts', '.tsx']);
+const SPECIALIZED_COLOR_OWNER_KINDS = new Set(['bespoke-theme', 'data-viz', 'game-renderer', 'slide-renderer']);
+const SURFACE_KINDS = new Set(['canonical-web', 'contract-owner', 'miniapp', 'native-mobile', 'terminal']);
+const AUDIT_ENGINES = new Set(['cli', 'miniapp', 'native', 'theme']);
+const CANONICAL_ZERO_METRICS = [
+ 'colorScopes.appUi.occurrences',
+ 'colorScopes.appUi.uniqueColors',
+ 'colorScopes.token.occurrences',
+ 'colorScopes.exception.occurrences',
+ 'fallbackOccurrences',
+ 'fallbackUniqueTokens',
+ 'fallbackContracts.uncontractedUnique',
+ 'compatibilityAliases.usedUnique',
+ 'compatibilityAliases.occurrences',
+ 'compatibilityAliases.familyUsedUnique',
+ 'compatibilityAliases.familyOccurrences',
+ 'compatibilityAliases.missingCanonicalUnique',
+ 'surfaceTokenRenames.activeUnique',
+ 'surfaceTokenRenames.activeOccurrences',
+ 'surfaceTokenRenames.missingCanonicalUnique',
+ 'tokenAliasLiterals.occurrences',
+ 'tokenAliasLiterals.uniqueColors',
+ 'cssVarDefinitions.unresolvedUnique',
+ 'cssVarDefinitions.unresolvedRequiredUnique',
+ 'cssVarDefinitions.fallbackOnlyUnique',
+ 'cssVarDefinitions.nonContractCrossFileUnique',
+ 'cssVarDefinitions.nonContractDynamicInputUnique',
+ 'cssVarDefinitions.nonContractCssPrivateUnique',
+ 'cssVarDefinitions.unregisteredDynamicFamilyUnique',
+ 'cssVarDefinitions.dynamicFamilyUnexportedUnique',
+ 'cssVarDefinitions.staleRegisteredDynamicFamilyUnique',
+ 'nearPairs.indistinguishableTotal',
+ 'nearPairs.nearTotal'
+];
+const HEX_COLOR_PATTERN = /(? value?.[key], object);
+}
+
+function pathIsWithinRoot(repositoryRoot, candidate) {
+ const relative = path.relative(repositoryRoot, candidate);
+ return relative !== '' && !relative.startsWith(`..${path.sep}`) && relative !== '..' && !path.isAbsolute(relative);
+}
+
+function resolveRegistryPath(repositoryRoot, relativePath, label, failures, { allowFile = true, allowDirectory = true } = {}) {
+ if (typeof relativePath !== 'string' || relativePath.trim() === '' || path.isAbsolute(relativePath)) {
+ failures.push(`${label} must be a non-empty repository-relative path.`);
+ return null;
+ }
+ const resolved = path.resolve(repositoryRoot, relativePath);
+ if (!pathIsWithinRoot(repositoryRoot, resolved)) {
+ failures.push(`${label} escapes the repository root: ${relativePath}`);
+ return null;
+ }
+ if (!fs.existsSync(resolved)) {
+ failures.push(`${label} does not exist: ${relativePath}`);
+ return null;
+ }
+ const stat = fs.statSync(resolved);
+ if ((!allowFile && stat.isFile()) || (!allowDirectory && stat.isDirectory())) {
+ failures.push(`${label} has the wrong path kind: ${relativePath}`);
+ }
+ return resolved;
+}
+
+export function validateRegistry(registry, { repositoryRoot = REPOSITORY_ROOT } = {}) {
+ const failures = [];
+ if (!registry || registry.version !== 1) {
+ return ['frontend color surface registry must use version 1.'];
+ }
+ if (!registry.contracts || typeof registry.contracts !== 'object') {
+ failures.push('registry.contracts must be an object.');
+ } else {
+ for (const [name, contractPath] of Object.entries(registry.contracts)) {
+ resolveRegistryPath(repositoryRoot, contractPath, `contracts.${name}`, failures, { allowDirectory: false });
+ }
+ }
+ if (!Array.isArray(registry.surfaces) || registry.surfaces.length === 0) {
+ failures.push('registry.surfaces must be a non-empty array.');
+ return failures;
+ }
+
+ const surfaceIds = new Set();
+ for (const [index, surface] of registry.surfaces.entries()) {
+ const label = `surfaces[${index}]`;
+ if (!/^[a-z0-9-]+$/.test(surface?.id ?? '')) failures.push(`${label}.id must be kebab-case.`);
+ if (surfaceIds.has(surface?.id)) failures.push(`${label}.id duplicates ${surface.id}.`);
+ surfaceIds.add(surface?.id);
+ if (typeof surface?.label !== 'string' || surface.label.trim() === '') failures.push(`${label}.label is required.`);
+ if (!SURFACE_KINDS.has(surface?.kind)) failures.push(`${label}.kind is invalid: ${String(surface?.kind)}`);
+ if (typeof surface?.owner !== 'string' || surface.owner.trim() === '') failures.push(`${label}.owner is required.`);
+
+ const roots = surface?.roots ?? (surface?.root ? [surface.root] : []);
+ if (!Array.isArray(roots) || roots.length === 0) failures.push(`${label} must declare root or roots.`);
+ for (const [rootIndex, root] of roots.entries()) {
+ resolveRegistryPath(repositoryRoot, root, `${label}.roots[${rootIndex}]`, failures, { allowFile: false });
+ }
+
+ if (surface.kind === 'contract-owner') {
+ if (surface.audit !== undefined) failures.push(`${label} contract owners must not declare an audit engine.`);
+ continue;
+ }
+ if (!surface.audit || !AUDIT_ENGINES.has(surface.audit.engine)) {
+ failures.push(`${label}.audit.engine is required and must be registered.`);
+ continue;
+ }
+ const expectedEngine = surface.kind === 'terminal'
+ ? 'cli'
+ : surface.kind === 'native-mobile'
+ ? 'native'
+ : surface.kind === 'miniapp'
+ ? 'miniapp'
+ : 'theme';
+ if (surface.audit.engine !== expectedEngine) {
+ failures.push(`${label}.audit.engine must be ${expectedEngine} for ${surface.kind}.`);
+ }
+ if (surface.audit.baseline) {
+ resolveRegistryPath(repositoryRoot, surface.audit.baseline, `${label}.audit.baseline`, failures, { allowDirectory: false });
+ }
+ for (const [excludeIndex, excludePath] of (surface.audit.excludePaths ?? []).entries()) {
+ resolveRegistryPath(
+ repositoryRoot,
+ path.join(surface.root, excludePath),
+ `${label}.audit.excludePaths[${excludeIndex}]`,
+ failures
+ );
+ }
+ for (const [excludeIndex, excludeFile] of (surface.audit.excludeFiles ?? []).entries()) {
+ resolveRegistryPath(
+ repositoryRoot,
+ path.join(surface.root, excludeFile),
+ `${label}.audit.excludeFiles[${excludeIndex}]`,
+ failures,
+ { allowDirectory: false }
+ );
+ }
+ for (const [ownerIndex, owner] of (surface.audit.rawColorOwners ?? []).entries()) {
+ const ownerLabel = `${label}.audit.rawColorOwners[${ownerIndex}]`;
+ if (!SPECIALIZED_COLOR_OWNER_KINDS.has(owner?.kind)) failures.push(`${ownerLabel}.kind is invalid.`);
+ if (typeof owner?.reason !== 'string' || owner.reason.trim().length < 24) failures.push(`${ownerLabel}.reason must explain the narrow owner.`);
+ const ownerFiles = [owner.file, ...(owner.files ?? []), ...(owner.pathPrefixes ?? [])].filter(Boolean);
+ if (ownerFiles.length === 0) failures.push(`${ownerLabel} must declare file, files, or pathPrefixes.`);
+ for (const [fileIndex, ownerFile] of ownerFiles.entries()) {
+ resolveRegistryPath(
+ repositoryRoot,
+ path.join(surface.root, ownerFile),
+ `${ownerLabel}.paths[${fileIndex}]`,
+ failures
+ );
+ }
+ if ((owner.startMarker && !owner.endMarker) || (!owner.startMarker && owner.endMarker)) {
+ failures.push(`${ownerLabel} must declare both startMarker and endMarker.`);
+ }
+ if (owner.linePattern) {
+ try {
+ new RegExp(owner.linePattern);
+ } catch (error) {
+ failures.push(`${ownerLabel}.linePattern is invalid: ${error instanceof Error ? error.message : String(error)}`);
+ }
+ }
+ }
+ for (const [bundleIndex, bundle] of (surface.audit.generatedBundles ?? []).entries()) {
+ const bundleLabel = `${label}.audit.generatedBundles[${bundleIndex}]`;
+ resolveRegistryPath(repositoryRoot, path.join(surface.root, bundle.output), `${bundleLabel}.output`, failures, { allowDirectory: false });
+ if (!Array.isArray(bundle.inputs) || bundle.inputs.length === 0) failures.push(`${bundleLabel}.inputs must be non-empty.`);
+ for (const [inputIndex, input] of (bundle.inputs ?? []).entries()) {
+ resolveRegistryPath(repositoryRoot, path.join(surface.root, input), `${bundleLabel}.inputs[${inputIndex}]`, failures, { allowDirectory: false });
+ }
+ }
+ }
+
+ const mirrorPaths = new Set();
+ for (const [index, mirror] of (registry.mirrors ?? []).entries()) {
+ const label = `mirrors[${index}]`;
+ const surface = registry.surfaces.find(candidate => candidate.id === mirror?.surfaceId);
+ if (!surface || surface.kind !== 'miniapp') failures.push(`${label}.surfaceId must name a MiniApp surface.`);
+ if (mirrorPaths.has(mirror?.path)) failures.push(`${label}.path duplicates ${mirror.path}.`);
+ mirrorPaths.add(mirror?.path);
+ resolveRegistryPath(repositoryRoot, mirror?.path, `${label}.path`, failures, { allowFile: false });
+ }
+
+ const discoveryParents = registry.discovery?.miniappParents;
+ if (!Array.isArray(discoveryParents) || discoveryParents.length === 0) {
+ failures.push('registry.discovery.miniappParents must be non-empty.');
+ } else {
+ for (const [index, parent] of discoveryParents.entries()) {
+ resolveRegistryPath(repositoryRoot, parent, `discovery.miniappParents[${index}]`, failures, { allowFile: false });
+ }
+ }
+
+ const generatedCheckIds = new Set();
+ for (const [index, check] of (registry.generatedChecks ?? []).entries()) {
+ const label = `generatedChecks[${index}]`;
+ if (!/^[a-z0-9-]+$/.test(check?.id ?? '')) failures.push(`${label}.id must be kebab-case.`);
+ if (generatedCheckIds.has(check?.id)) failures.push(`${label}.id duplicates ${check.id}.`);
+ generatedCheckIds.add(check?.id);
+ if (!Array.isArray(check?.command) || check.command.length < 2 || check.command.some(part => typeof part !== 'string' || part === '')) {
+ failures.push(`${label}.command must be a non-empty string array.`);
+ }
+ for (const surfaceId of check?.surfaceIds ?? []) {
+ if (!surfaceIds.has(surfaceId)) failures.push(`${label}.surfaceIds references unknown surface ${surfaceId}.`);
+ }
+ for (const kind of check?.surfaceKinds ?? []) {
+ if (!SURFACE_KINDS.has(kind)) failures.push(`${label}.surfaceKinds references unknown kind ${kind}.`);
+ }
+ }
+
+ const exclusionIds = new Set();
+ for (const [index, exclusion] of (registry.exclusions ?? []).entries()) {
+ const label = `exclusions[${index}]`;
+ if (!/^[a-z0-9-]+$/.test(exclusion?.id ?? '')) failures.push(`${label}.id must be kebab-case.`);
+ if (exclusionIds.has(exclusion?.id)) failures.push(`${label}.id duplicates ${exclusion.id}.`);
+ exclusionIds.add(exclusion?.id);
+ resolveRegistryPath(repositoryRoot, exclusion?.path, `${label}.path`, failures);
+ if (typeof exclusion?.kind !== 'string' || exclusion.kind.trim() === '') failures.push(`${label}.kind is required.`);
+ if (typeof exclusion?.owner !== 'string' || exclusion.owner.trim() === '') failures.push(`${label}.owner is required.`);
+ if (typeof exclusion?.reason !== 'string' || exclusion.reason.trim().length < 24) failures.push(`${label}.reason must explain the boundary.`);
+ }
+ return failures;
+}
+
+function walkFiles(root, { extensions, excludePaths = [], excludeFiles = [] } = {}) {
+ const files = [];
+ const normalizedExcludePaths = excludePaths.map(normalizeRelativePath);
+ const normalizedExcludeFiles = new Set(excludeFiles.map(normalizeRelativePath));
+ const stack = [root];
+ while (stack.length > 0) {
+ const current = stack.pop();
+ for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
+ const fullPath = path.join(current, entry.name);
+ const relativePath = normalizePath(path.relative(root, fullPath));
+ const excluded = normalizedExcludeFiles.has(relativePath) || normalizedExcludePaths.some(prefix => (
+ relativePath === prefix || relativePath.startsWith(`${prefix}/`)
+ ));
+ if (excluded) continue;
+ if (entry.isDirectory()) {
+ if (entry.name === 'node_modules' || entry.name === '.git') continue;
+ stack.push(fullPath);
+ } else if (entry.isFile() && (!extensions || extensions.has(path.extname(entry.name).toLowerCase()))) {
+ files.push(fullPath);
+ }
+ }
+ }
+ return files.sort((left, right) => left.localeCompare(right));
+}
+
+function addFinding(findings, seen, { file, content, index, value, type }) {
+ const key = `${file}:${index}:${type}:${value.toLowerCase()}`;
+ if (seen.has(key)) return;
+ seen.add(key);
+ const line = content.slice(0, index).split(/\r?\n/).length;
+ const lineText = content.split(/\r?\n/)[line - 1] ?? '';
+ findings.push({ file, index, line, lineText, type, value });
+}
+
+function collectRawColorFindings(relativePath, content) {
+ const findings = [];
+ const seen = new Set();
+ for (const pattern of [HEX_COLOR_PATTERN, FUNCTION_COLOR_PATTERN]) {
+ pattern.lastIndex = 0;
+ for (const match of content.matchAll(pattern)) {
+ addFinding(findings, seen, {
+ file: relativePath,
+ content,
+ index: match.index,
+ value: match[0],
+ type: match[0].startsWith('#') ? 'hex' : 'color-function'
+ });
+ }
+ }
+
+ const extension = path.extname(relativePath).toLowerCase();
+ if (['.css', '.html', '.scss', '.svg'].includes(extension)) {
+ CSS_DECLARATION_PATTERN.lastIndex = 0;
+ for (const declaration of content.matchAll(CSS_DECLARATION_PATTERN)) {
+ const value = declaration[1].replace(/url\((?:\"[^\"]*\"|'[^']*'|[^)]*)\)/gi, ' ');
+ CSS_NAMED_COLOR_PATTERN.lastIndex = 0;
+ for (const match of value.matchAll(CSS_NAMED_COLOR_PATTERN)) {
+ addFinding(findings, seen, {
+ file: relativePath,
+ content,
+ index: declaration.index + declaration[0].indexOf(declaration[1]) + match.index + match[0].lastIndexOf(match[1]),
+ value: match[1],
+ type: 'named-color'
+ });
+ }
+ }
+ CSS_COLOR_ATTRIBUTE_PATTERN.lastIndex = 0;
+ for (const match of content.matchAll(CSS_COLOR_ATTRIBUTE_PATTERN)) {
+ addFinding(findings, seen, {
+ file: relativePath,
+ content,
+ index: match.index + match[0].lastIndexOf(match[1]),
+ value: match[1],
+ type: 'named-color'
+ });
+ }
+ } else {
+ SCRIPT_COLOR_VALUE_PATTERN.lastIndex = 0;
+ for (const match of content.matchAll(SCRIPT_COLOR_VALUE_PATTERN)) {
+ addFinding(findings, seen, {
+ file: relativePath,
+ content,
+ index: match.index + match[0].lastIndexOf(match[1]),
+ value: match[1],
+ type: 'named-color'
+ });
+ }
+ }
+ return findings.sort((left, right) => left.index - right.index);
+}
+
+function ownerMatchesFinding(owner, finding, content) {
+ const ownerPaths = [owner.file, ...(owner.files ?? []), ...(owner.pathPrefixes ?? [])]
+ .filter(Boolean)
+ .map(normalizeRelativePath);
+ const pathMatches = ownerPaths.some(ownerPath => (
+ finding.file === ownerPath || finding.file.startsWith(`${ownerPath}/`)
+ ));
+ if (!pathMatches) return false;
+ if (owner.startMarker) {
+ const start = content.indexOf(owner.startMarker);
+ const end = start < 0 ? -1 : content.indexOf(owner.endMarker, start + owner.startMarker.length);
+ if (start < 0 || end < 0 || finding.index < start || finding.index > end + owner.endMarker.length) return false;
+ }
+ if (owner.linePattern && !new RegExp(owner.linePattern).test(finding.lineText)) return false;
+ return true;
+}
+
+function checkGeneratedBundles(surface, repositoryRoot) {
+ const failures = [];
+ for (const bundle of surface.audit.generatedBundles ?? []) {
+ const outputRelative = normalizeRelativePath(bundle.output);
+ const outputDirectory = path.posix.dirname(outputRelative);
+ const expected = bundle.inputs.map((input) => {
+ const normalizedInput = normalizeRelativePath(input);
+ const label = path.posix.relative(outputDirectory, normalizedInput);
+ const content = fs.readFileSync(path.join(repositoryRoot, surface.root, normalizedInput), 'utf8');
+ return `/* ${label} */\n${content}\n`;
+ }).join('');
+ const actual = fs.readFileSync(path.join(repositoryRoot, surface.root, outputRelative), 'utf8');
+ if (actual !== expected) {
+ failures.push(`${surface.id} generated bundle ${bundle.output} is stale; run its source/build.js.`);
+ }
+ }
+ return failures;
+}
+
+export function auditMiniappSurface(surface, contract, { repositoryRoot = REPOSITORY_ROOT } = {}) {
+ const root = path.join(repositoryRoot, surface.root);
+ const files = walkFiles(root, {
+ extensions: MINIAPP_SOURCE_EXTENSIONS,
+ excludePaths: surface.audit.excludePaths ?? [],
+ excludeFiles: surface.audit.excludeFiles ?? []
+ });
+ const allowedHostVariables = new Set(contract.variables.map(variable => variable.name));
+ const rawOwnerMatches = new Map((surface.audit.rawColorOwners ?? []).map((owner, index) => [index, 0]));
+ const failures = [];
+ const rawFindings = [];
+ const hostVariables = new Set();
+ let hostVariableOccurrences = 0;
+
+ for (const file of files) {
+ const relativePath = normalizePath(path.relative(root, file));
+ const content = fs.readFileSync(file, 'utf8');
+ for (const finding of collectRawColorFindings(relativePath, content)) {
+ const ownerIndex = (surface.audit.rawColorOwners ?? []).findIndex(owner => ownerMatchesFinding(owner, finding, content));
+ if (ownerIndex < 0) {
+ rawFindings.push(finding);
+ failures.push(`${surface.id}:${finding.file}:${finding.line} has unowned ${finding.type} ${finding.value}.`);
+ } else {
+ rawOwnerMatches.set(ownerIndex, (rawOwnerMatches.get(ownerIndex) ?? 0) + 1);
+ }
+ }
+
+ HOST_VARIABLE_PATTERN.lastIndex = 0;
+ for (const match of content.matchAll(HOST_VARIABLE_PATTERN)) {
+ hostVariables.add(match[0]);
+ hostVariableOccurrences += 1;
+ if (!allowedHostVariables.has(match[0])) {
+ const line = content.slice(0, match.index).split(/\r?\n/).length;
+ failures.push(`${surface.id}:${relativePath}:${line} uses unregistered MiniApp appearance variable ${match[0]}.`);
+ }
+ }
+ HOST_VARIABLE_FALLBACK_PATTERN.lastIndex = 0;
+ for (const match of content.matchAll(HOST_VARIABLE_FALLBACK_PATTERN)) {
+ const line = content.slice(0, match.index).split(/\r?\n/).length;
+ failures.push(`${surface.id}:${relativePath}:${line} adds a fallback to public host variable ${match[1]}.`);
+ }
+ HOST_VARIABLE_DEFINITION_PATTERN.lastIndex = 0;
+ for (const match of content.matchAll(HOST_VARIABLE_DEFINITION_PATTERN)) {
+ const line = content.slice(0, match.index).split(/\r?\n/).length;
+ failures.push(`${surface.id}:${relativePath}:${line} redefines host-owned MiniApp variable ${match[1]}.`);
+ }
+ }
+
+ for (const [ownerIndex, count] of rawOwnerMatches) {
+ if (count === 0) {
+ const owner = surface.audit.rawColorOwners[ownerIndex];
+ failures.push(`${surface.id} specialized owner ${owner.kind} is stale; remove or narrow the registry entry.`);
+ }
+ }
+ failures.push(...checkGeneratedBundles(surface, repositoryRoot));
+ return {
+ surfaceId: surface.id,
+ engine: 'miniapp',
+ filesScanned: files.length,
+ hostVariableOccurrences,
+ hostVariables: Array.from(hostVariables).sort(),
+ unownedRawColors: rawFindings,
+ specializedOwners: (surface.audit.rawColorOwners ?? []).map((owner, index) => ({
+ kind: owner.kind,
+ occurrences: rawOwnerMatches.get(index) ?? 0
+ })),
+ failures
+ };
+}
+
+const NATIVE_PATTERNS = {
+ android: [
+ { type: 'named-native-color', pattern: /\bColor\.(?:Black|White|Red|Green|Blue|Yellow|Gray|Magenta|Cyan|Transparent)\b/g },
+ { type: 'native-color-constructor', pattern: /\bColor\s*\(\s*0x[0-9a-fA-F_]+\s*\)/g },
+ { type: 'native-color-function', pattern: /\b(?:android\.graphics\.)?Color\.(?:argb|rgb|parseColor)\s*\(/g },
+ { type: 'hex-string', pattern: /['\"]#[0-9a-fA-F]{3,8}\b/g }
+ ],
+ ios: [
+ { type: 'named-native-color', pattern: /(? (
+ `${surface.id}:${finding.file}:${finding.line} has raw native color ${finding.value}.`
+ ));
+ if (files.length === 0) failures.push(`${surface.id} scanned no native source files.`);
+ return {
+ surfaceId: surface.id,
+ engine: 'native',
+ platform: surface.audit.platform,
+ filesScanned: files.length,
+ rawColorOccurrences: findings.length,
+ findings,
+ failures
+ };
+}
+
+function listTreeFiles(root) {
+ return walkFiles(root).map(file => normalizePath(path.relative(root, file)));
+}
+
+export function compareMirrorTrees(sourceRoot, mirrorRoot) {
+ const sourceFiles = listTreeFiles(sourceRoot);
+ const mirrorFiles = listTreeFiles(mirrorRoot);
+ const sourceSet = new Set(sourceFiles);
+ const mirrorSet = new Set(mirrorFiles);
+ const failures = [];
+ for (const file of sourceFiles) {
+ if (!mirrorSet.has(file)) {
+ failures.push(`mirror is missing ${file}`);
+ continue;
+ }
+ const source = fs.readFileSync(path.join(sourceRoot, file));
+ const mirror = fs.readFileSync(path.join(mirrorRoot, file));
+ if (!source.equals(mirror)) failures.push(`mirror differs at ${file}`);
+ }
+ for (const file of mirrorFiles) {
+ if (!sourceSet.has(file)) failures.push(`mirror has extra file ${file}`);
+ }
+ return failures;
+}
+
+export function discoverMiniappRoots(registry, { repositoryRoot = REPOSITORY_ROOT } = {}) {
+ const discovered = [];
+ for (const parentPath of registry.discovery.miniappParents) {
+ const parent = path.join(repositoryRoot, parentPath);
+ for (const entry of fs.readdirSync(parent, { withFileTypes: true })) {
+ if (!entry.isDirectory()) continue;
+ const appRoot = path.join(parent, entry.name);
+ if (fs.existsSync(path.join(appRoot, 'meta.json'))) {
+ discovered.push(normalizePath(path.relative(repositoryRoot, appRoot)));
+ }
+ }
+ }
+ return discovered.sort();
+}
+
+function auditMiniappDiscovery(registry, repositoryRoot) {
+ const registered = new Set([
+ ...registry.surfaces.filter(surface => surface.kind === 'miniapp').map(surface => normalizeRelativePath(surface.root)),
+ ...(registry.mirrors ?? []).map(mirror => normalizeRelativePath(mirror.path))
+ ]);
+ const discovered = discoverMiniappRoots(registry, { repositoryRoot });
+ const discoveredSet = new Set(discovered);
+ const failures = [];
+ for (const root of discovered) {
+ if (!registered.has(root)) failures.push(`Unregistered MiniApp discovered at ${root}.`);
+ }
+ for (const root of registered) {
+ if (!discoveredSet.has(root)) failures.push(`Registered MiniApp path is not discoverable: ${root}.`);
+ }
+ return { discovered, registered: Array.from(registered).sort(), failures };
+}
+
+function runSubprocess(command, args, repositoryRoot) {
+ return spawnSync(command, args, {
+ cwd: repositoryRoot,
+ encoding: 'utf8',
+ env: process.env,
+ maxBuffer: 64 * 1024 * 1024
+ });
+}
+
+function parseJsonOutput(result, label) {
+ if (!result.stdout?.trim()) {
+ return { report: null, failures: [`${label} returned no JSON output. ${result.stderr?.trim() ?? ''}`.trim()] };
+ }
+ try {
+ return { report: JSON.parse(result.stdout), failures: [] };
+ } catch (error) {
+ return {
+ report: null,
+ failures: [`${label} returned invalid JSON: ${error instanceof Error ? error.message : String(error)}`]
+ };
+ }
+}
+
+function auditThemeSurface(surface, repositoryRoot) {
+ const args = [THEME_AUDITOR_PATH, '--root', surface.root, '--json', '--top', '0'];
+ if (surface.audit.baseline) args.push('--baseline', surface.audit.baseline);
+ else args.push('--no-baseline');
+ for (const packageName of surface.audit.packageContracts ?? []) args.push('--package-contract', packageName);
+ for (const excludePath of surface.audit.excludePaths ?? []) args.push('--exclude', excludePath);
+ const result = runSubprocess(process.execPath, args, repositoryRoot);
+ const parsed = parseJsonOutput(result, `${surface.id} theme audit`);
+ const failures = [...parsed.failures];
+ if (result.status !== 0) {
+ failures.push(`${surface.id} theme audit failed: ${result.stderr?.trim() || `exit ${result.status}`}`);
+ }
+ if (parsed.report?.filesScanned === 0) failures.push(`${surface.id} theme audit scanned no files.`);
+ if (surface.audit.policy === 'canonical-ui-zero' && parsed.report) {
+ for (const metric of CANONICAL_ZERO_METRICS) {
+ const actual = getPathValue(parsed.report, metric);
+ if (typeof actual !== 'number') failures.push(`${surface.id} canonical policy references missing metric ${metric}.`);
+ else if (actual !== 0) failures.push(`${surface.id} ${metric} must be 0, found ${actual}.`);
+ }
+ }
+ return { surfaceId: surface.id, engine: 'theme', report: parsed.report, failures };
+}
+
+function auditCliSurface(surface, repositoryRoot) {
+ const args = [CLI_AUDITOR_PATH, '--root', surface.root, '--json'];
+ if (surface.audit.baseline) args.push('--baseline', surface.audit.baseline);
+ else args.push('--no-baseline');
+ const result = runSubprocess(process.execPath, args, repositoryRoot);
+ const parsed = parseJsonOutput(result, `${surface.id} CLI audit`);
+ const failures = [...parsed.failures];
+ if (result.status !== 0) failures.push(`${surface.id} CLI audit failed: ${result.stderr?.trim() || `exit ${result.status}`}`);
+ return { surfaceId: surface.id, engine: 'cli', report: parsed.report, failures };
+}
+
+function generatedCheckApplies(check, selectedSurfaces) {
+ const selectedIds = new Set(selectedSurfaces.map(surface => surface.id));
+ const selectedKinds = new Set(selectedSurfaces.map(surface => surface.kind));
+ return (check.surfaceIds ?? []).some(id => selectedIds.has(id))
+ || (check.surfaceKinds ?? []).some(kind => selectedKinds.has(kind));
+}
+
+function runGeneratedCheck(check, repositoryRoot) {
+ const [executable, ...args] = check.command;
+ const command = executable === 'node' ? process.execPath : executable;
+ const result = runSubprocess(command, args, repositoryRoot);
+ return {
+ id: check.id,
+ status: result.status,
+ output: [result.stdout, result.stderr].filter(Boolean).join('\n').trim(),
+ failures: result.status === 0
+ ? []
+ : [`Generated artifact check ${check.id} failed: ${[result.stdout, result.stderr].filter(Boolean).join('\n').trim()}`]
+ };
+}
+
+export function loadRegistry(registryPath = DEFAULT_REGISTRY_PATH) {
+ return JSON.parse(fs.readFileSync(registryPath, 'utf8'));
+}
+
+export function runFrontendColorAudit({
+ registry,
+ repositoryRoot = REPOSITORY_ROOT,
+ surfaceIds = [],
+ surfaceKinds = [],
+ runGeneratedChecks = true
+}) {
+ const failures = validateRegistry(registry, { repositoryRoot });
+ const requestedIds = new Set(surfaceIds);
+ const requestedKinds = new Set(surfaceKinds);
+ const hasFilter = requestedIds.size > 0 || requestedKinds.size > 0;
+ for (const id of requestedIds) {
+ if (!registry.surfaces.some(surface => surface.id === id)) failures.push(`Unknown frontend color surface: ${id}.`);
+ }
+ for (const kind of requestedKinds) {
+ if (!SURFACE_KINDS.has(kind)) failures.push(`Unknown frontend color surface kind: ${kind}.`);
+ }
+ if (failures.length > 0) {
+ return { registryVersion: registry.version, surfaces: [], discovery: null, mirrors: [], generatedChecks: [], failures };
+ }
+
+ const selectedSurfaces = registry.surfaces.filter(surface => (
+ !hasFilter || requestedIds.has(surface.id) || requestedKinds.has(surface.kind)
+ ));
+ const miniappContract = JSON.parse(fs.readFileSync(path.join(repositoryRoot, registry.contracts.miniappAppearance), 'utf8'));
+ const surfaceReports = [];
+ for (const surface of selectedSurfaces) {
+ let report;
+ if (surface.kind === 'contract-owner') {
+ report = { surfaceId: surface.id, engine: 'contract-owner', roots: surface.roots, failures: [] };
+ } else if (surface.audit.engine === 'theme') {
+ report = auditThemeSurface(surface, repositoryRoot);
+ } else if (surface.audit.engine === 'cli') {
+ report = auditCliSurface(surface, repositoryRoot);
+ } else if (surface.audit.engine === 'native') {
+ report = auditNativeSurface(surface, { repositoryRoot });
+ } else {
+ report = auditMiniappSurface(surface, miniappContract, { repositoryRoot });
+ }
+ surfaceReports.push(report);
+ failures.push(...report.failures);
+ }
+
+ const selectedMiniapps = selectedSurfaces.filter(surface => surface.kind === 'miniapp');
+ const shouldAuditAllMiniappDiscovery = !hasFilter || requestedKinds.has('miniapp');
+ const discovery = shouldAuditAllMiniappDiscovery ? auditMiniappDiscovery(registry, repositoryRoot) : null;
+ if (discovery) failures.push(...discovery.failures);
+
+ const selectedMiniappIds = new Set(selectedMiniapps.map(surface => surface.id));
+ const mirrorReports = (registry.mirrors ?? [])
+ .filter(mirror => !hasFilter || selectedMiniappIds.has(mirror.surfaceId) || requestedKinds.has('miniapp'))
+ .map((mirror) => {
+ const surface = registry.surfaces.find(candidate => candidate.id === mirror.surfaceId);
+ const mirrorFailures = compareMirrorTrees(
+ path.join(repositoryRoot, surface.root),
+ path.join(repositoryRoot, mirror.path)
+ ).map(failure => `${mirror.surfaceId} reference ${mirror.path}: ${failure}.`);
+ failures.push(...mirrorFailures);
+ return { surfaceId: mirror.surfaceId, path: mirror.path, failures: mirrorFailures };
+ });
+
+ const generatedReports = runGeneratedChecks
+ ? (registry.generatedChecks ?? [])
+ .filter(check => generatedCheckApplies(check, selectedSurfaces))
+ .map((check) => {
+ const report = runGeneratedCheck(check, repositoryRoot);
+ failures.push(...report.failures);
+ return report;
+ })
+ : [];
+ return {
+ registryVersion: registry.version,
+ selectedSurfaceIds: selectedSurfaces.map(surface => surface.id),
+ surfaces: surfaceReports,
+ discovery,
+ mirrors: mirrorReports,
+ generatedChecks: generatedReports,
+ failures
+ };
+}
+
+function parseArgs(argv) {
+ const options = {
+ registryPath: DEFAULT_REGISTRY_PATH,
+ surfaceIds: [],
+ surfaceKinds: [],
+ json: false,
+ list: false,
+ runGeneratedChecks: true
+ };
+ for (let index = 0; index < argv.length; index += 1) {
+ const arg = argv[index];
+ if (arg === '--registry') options.registryPath = path.resolve(argv[++index] ?? '');
+ else if (arg.startsWith('--registry=')) options.registryPath = path.resolve(arg.slice('--registry='.length));
+ else if (arg === '--surface') options.surfaceIds.push(argv[++index] ?? '');
+ else if (arg.startsWith('--surface=')) options.surfaceIds.push(arg.slice('--surface='.length));
+ else if (arg === '--kind') options.surfaceKinds.push(argv[++index] ?? '');
+ else if (arg.startsWith('--kind=')) options.surfaceKinds.push(arg.slice('--kind='.length));
+ else if (arg === '--json') options.json = true;
+ else if (arg === '--list') options.list = true;
+ else if (arg === '--skip-generated-checks') options.runGeneratedChecks = false;
+ else if (arg === '--help' || arg === '-h') {
+ console.log('Usage: node scripts/audit-frontend-colors.mjs [--surface ] [--kind ] [--json] [--list]');
+ process.exit(0);
+ } else throw new Error(`Unknown argument: ${arg}`);
+ }
+ return options;
+}
+
+function formatSurfaceSummary(surfaceReport) {
+ if (surfaceReport.engine === 'theme') {
+ const report = surfaceReport.report;
+ return `${report?.filesScanned ?? 0} files, app raw=${report?.colorScopes?.appUi?.occurrences ?? '?'}, fallbacks=${report?.fallbackOccurrences ?? '?'}`;
+ }
+ if (surfaceReport.engine === 'cli') {
+ return `${surfaceReport.report?.presetFiles ?? 0} presets, runtime colors=${surfaceReport.report?.runtimePresetUniqueColors ?? '?'}`;
+ }
+ if (surfaceReport.engine === 'native') {
+ return `${surfaceReport.filesScanned} files, raw=${surfaceReport.rawColorOccurrences}`;
+ }
+ if (surfaceReport.engine === 'miniapp') {
+ const specialized = surfaceReport.specializedOwners.map(owner => `${owner.kind}:${owner.occurrences}`).join(', ') || 'none';
+ return `${surfaceReport.filesScanned} files, host vars=${surfaceReport.hostVariableOccurrences}, specialized=${specialized}`;
+ }
+ return `${surfaceReport.roots.length} owner roots`;
+}
+
+function main() {
+ const options = parseArgs(process.argv.slice(2));
+ const registry = loadRegistry(options.registryPath);
+ if (options.list) {
+ for (const surface of registry.surfaces) console.log(`${surface.id}\t${surface.kind}\t${surface.label}`);
+ return;
+ }
+ const report = runFrontendColorAudit({
+ registry,
+ repositoryRoot: REPOSITORY_ROOT,
+ surfaceIds: options.surfaceIds,
+ surfaceKinds: options.surfaceKinds,
+ runGeneratedChecks: options.runGeneratedChecks
+ });
+ if (options.json) {
+ console.log(JSON.stringify(report, null, 2));
+ } else {
+ for (const surfaceReport of report.surfaces) {
+ const mark = surfaceReport.failures.length === 0 ? 'ok' : 'failed';
+ console.log(`[frontend-colors] ${mark} ${surfaceReport.surfaceId}: ${formatSurfaceSummary(surfaceReport)}`);
+ }
+ if (report.discovery) {
+ console.log(`[frontend-colors] ${report.discovery.failures.length === 0 ? 'ok' : 'failed'} MiniApp discovery: ${report.discovery.discovered.length} registered roots`);
+ }
+ for (const mirror of report.mirrors) {
+ console.log(`[frontend-colors] ${mirror.failures.length === 0 ? 'ok' : 'failed'} mirror ${mirror.surfaceId}`);
+ }
+ for (const check of report.generatedChecks) {
+ console.log(`[frontend-colors] ${check.failures.length === 0 ? 'ok' : 'failed'} generated ${check.id}`);
+ }
+ if (report.failures.length > 0) {
+ console.error('\nFrontend color governance failures:');
+ for (const failure of report.failures) console.error(`- ${failure}`);
+ } else {
+ console.log(`[frontend-colors] all ${report.selectedSurfaceIds.length} selected surfaces passed.`);
+ }
+ }
+ if (report.failures.length > 0) process.exitCode = 1;
+}
+
+if (process.argv[1] && path.resolve(process.argv[1]) === SCRIPT_PATH) {
+ main();
+}
diff --git a/scripts/audit-frontend-colors.test.mjs b/scripts/audit-frontend-colors.test.mjs
new file mode 100644
index 0000000000..096acec427
--- /dev/null
+++ b/scripts/audit-frontend-colors.test.mjs
@@ -0,0 +1,97 @@
+import assert from 'node:assert/strict';
+import fs from 'node:fs';
+import os from 'node:os';
+import path from 'node:path';
+import test from 'node:test';
+
+import {
+ auditMiniappSurface,
+ auditNativeSurface,
+ compareMirrorTrees,
+ discoverMiniappRoots,
+ loadRegistry,
+ validateRegistry,
+} from './audit-frontend-colors.mjs';
+
+const repositoryRoot = process.cwd();
+
+function writeText(filePath, content) {
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
+ fs.writeFileSync(filePath, content, 'utf8');
+}
+
+test('frontend color surface registry covers every discovered MiniApp and names valid owners', () => {
+ const registry = loadRegistry();
+ assert.deepEqual(validateRegistry(registry, { repositoryRoot }), []);
+
+ const registered = new Set([
+ ...registry.surfaces.filter(surface => surface.kind === 'miniapp').map(surface => surface.root),
+ ...registry.mirrors.map(mirror => mirror.path),
+ ]);
+ assert.deepEqual(discoverMiniappRoots(registry, { repositoryRoot }), Array.from(registered).sort());
+ assert.ok(registry.exclusions.every(exclusion => exclusion.owner && exclusion.reason.length >= 24));
+});
+
+test('MiniApp audit accepts a narrow data-viz owner and rejects ordinary raw colors or host fallbacks', (t) => {
+ const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'bitfun-miniapp-colors-'));
+ t.after(() => fs.rmSync(fixtureRoot, { recursive: true, force: true }));
+ writeText(path.join(fixtureRoot, 'app/ui.js'), "const SERIES = ['#ff00ff'];\n");
+ writeText(path.join(fixtureRoot, 'app/style.css'), '.app { color: #ffffff; background: var(--bitfun-bg, #000000); }\n');
+ const surface = {
+ id: 'fixture-miniapp',
+ root: 'app',
+ audit: {
+ engine: 'miniapp',
+ rawColorOwners: [{
+ kind: 'data-viz',
+ file: 'ui.js',
+ startMarker: 'const SERIES = [',
+ endMarker: '];',
+ reason: 'Fixture categorical renderer palette owner.',
+ }],
+ },
+ };
+ const contract = {
+ variables: [{ name: '--bitfun-bg' }],
+ };
+
+ const report = auditMiniappSurface(surface, contract, { repositoryRoot: fixtureRoot });
+ assert.equal(report.specializedOwners[0].occurrences, 1);
+ assert.match(report.failures.join('\n'), /unowned hex #ffffff/);
+ assert.match(report.failures.join('\n'), /fallback to public host variable --bitfun-bg/);
+});
+
+test('native source audit rejects raw platform colors while ignoring generated projections', (t) => {
+ const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'bitfun-native-colors-'));
+ t.after(() => fs.rmSync(fixtureRoot, { recursive: true, force: true }));
+ writeText(path.join(fixtureRoot, 'android/ui/Screen.kt'), 'val color = Color.White\n');
+ writeText(path.join(fixtureRoot, 'android/generated/Tokens.kt'), 'val color = Color.Black\n');
+ const surface = {
+ id: 'fixture-android',
+ root: 'android',
+ audit: {
+ engine: 'native',
+ platform: 'android',
+ extensions: ['.kt'],
+ excludePaths: ['generated'],
+ },
+ };
+
+ const report = auditNativeSurface(surface, { repositoryRoot: fixtureRoot });
+ assert.equal(report.filesScanned, 1);
+ assert.equal(report.rawColorOccurrences, 1);
+ assert.match(report.failures[0], /Color\.White/);
+});
+
+test('MiniApp reference mirrors are byte-exact, including file inventory', (t) => {
+ const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'bitfun-miniapp-mirror-'));
+ t.after(() => fs.rmSync(fixtureRoot, { recursive: true, force: true }));
+ const source = path.join(fixtureRoot, 'source');
+ const mirror = path.join(fixtureRoot, 'mirror');
+ writeText(path.join(source, 'style.css'), '.app {}\n');
+ writeText(path.join(mirror, 'style.css'), '.app {}\n');
+ assert.deepEqual(compareMirrorTrees(source, mirror), []);
+
+ writeText(path.join(mirror, 'style.css'), '.app { display: block; }\n');
+ assert.deepEqual(compareMirrorTrees(source, mirror), ['mirror differs at style.css']);
+});
diff --git a/scripts/audit-theme-colors.mjs b/scripts/audit-theme-colors.mjs
index e94f71a391..b2676441be 100644
--- a/scripts/audit-theme-colors.mjs
+++ b/scripts/audit-theme-colors.mjs
@@ -17,6 +17,7 @@ import {
EXCEPTION_PATH_PARTS,
FALLBACK_VAR_CONTRACTS,
PACKAGE_CSS_VAR_DEFINITION_CONTRACTS,
+ PACKAGE_CSS_VAR_IMPORT_CONTRACTS,
REGISTERED_DYNAMIC_VAR_PREFIXES,
RUNTIME_CONTRACT_VAR_DEFINITION_PATH_PARTS,
STATIC_CONTRACT_VAR_DEFINITION_PATH_PARTS,
@@ -30,6 +31,68 @@ import { writeReportJson } from './theme-color-audit-utils.mjs';
const COLOR_PATTERN =
/#[0-9a-fA-F]{3,8}\b|rgba?\(\s*[-+]?\d*\.?\d+\s*,\s*[-+]?\d*\.?\d+\s*,\s*[-+]?\d*\.?\d+(?:\s*,\s*(?:[-+]?\d*\.?\d+|var\([^)]+\)))?\s*\)|hsla?\(\s*[-+]?\d*\.?\d+(?:deg|rad|turn)?\s*,\s*[-+]?\d*\.?\d+%\s*,\s*[-+]?\d*\.?\d+%(?:\s*,\s*(?:[-+]?\d*\.?\d+|var\([^)]+\)))?\s*\)/g;
+const CSS_NAMED_COLORS = new Set(`
+ aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue
+ blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson
+ cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta
+ darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray
+ darkslategrey darkturquoise darkviolet deeppink deepskyblue dimgray dimgrey dodgerblue firebrick
+ floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow grey
+ honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon
+ lightblue lightcoral lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey lightpink
+ lightsalmon lightseagreen lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime
+ limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen
+ mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose
+ moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen
+ paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple rebeccapurple red
+ rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue
+ slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white
+ whitesmoke yellow yellowgreen
+`.trim().split(/\s+/));
+const CSS_NAMED_COLOR_PATTERN = new RegExp(
+ `(?:^|[^\\w-])(${Array.from(CSS_NAMED_COLORS).sort((a, b) => b.length - a.length).join('|')})(?![\\w-])`,
+ 'gi',
+);
+const COMMON_NAMED_COLOR_RGB = new Map([
+ ['black', [0, 0, 0]],
+ ['silver', [192, 192, 192]],
+ ['gray', [128, 128, 128]],
+ ['grey', [128, 128, 128]],
+ ['white', [255, 255, 255]],
+ ['maroon', [128, 0, 0]],
+ ['red', [255, 0, 0]],
+ ['purple', [128, 0, 128]],
+ ['fuchsia', [255, 0, 255]],
+ ['magenta', [255, 0, 255]],
+ ['green', [0, 128, 0]],
+ ['lime', [0, 255, 0]],
+ ['olive', [128, 128, 0]],
+ ['yellow', [255, 255, 0]],
+ ['navy', [0, 0, 128]],
+ ['blue', [0, 0, 255]],
+ ['teal', [0, 128, 128]],
+ ['aqua', [0, 255, 255]],
+ ['cyan', [0, 255, 255]],
+ ['orange', [255, 165, 0]],
+ ['rebeccapurple', [102, 51, 153]],
+]);
+const STYLE_SOURCE_EXTENSIONS = new Set(['.css', '.less', '.sass', '.scss']);
+const MARKUP_SOURCE_EXTENSIONS = new Set(['.html', '.svg']);
+const CSS_DECLARATION_PATTERN =
+ /(?:^|[;{])\s*((?:--|\$)?[a-zA-Z_][a-zA-Z0-9_-]*)\s*:\s*([^;{}]+)/gm;
+const CSS_COLOR_ATTRIBUTE_PATTERN = new RegExp(
+ `(?:^|[^\\w-])(?:color|fill|stroke|stop-color|flood-color|lighting-color)\\s*=\\s*['"](${Array.from(CSS_NAMED_COLORS).join('|')})['"]`,
+ 'gi',
+);
+const SCRIPT_COLOR_VALUE_PATTERN = new RegExp(
+ `(?:^|[,{;\\s])(?:color|backgroundColor|borderColor|outlineColor|caretColor|textDecorationColor|fill|stroke)\\s*:\\s*['"\\x60](${Array.from(CSS_NAMED_COLORS).join('|')})['"\\x60]`,
+ 'gi',
+);
+const RGB_CHANNEL_SOURCE = '(?:25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)';
+const RAW_RGB_CHANNEL_DEFINITION_PATTERN = new RegExp(
+ `(?:^|[;{])\\s*(?:--|\\$)[a-zA-Z_][a-zA-Z0-9_-]*\\s*:\\s*(${RGB_CHANNEL_SOURCE}\\s*,\\s*${RGB_CHANNEL_SOURCE}\\s*,\\s*${RGB_CHANNEL_SOURCE})\\s*(?=;|})`,
+ 'gm',
+);
const TOKEN_ALIAS_DEFINITION_PATTERN =
/(?:^|[;{\s])(\$[a-zA-Z0-9_-]+|--[a-zA-Z0-9_-]+)\s*:\s*(#[0-9a-fA-F]{3,8}\b|rgba?\(\s*[-+]?\d*\.?\d+\s*,\s*[-+]?\d*\.?\d+\s*,\s*[-+]?\d*\.?\d+(?:\s*,\s*(?:[-+]?\d*\.?\d+|var\([^)]+\)))?\s*\)|hsla?\(\s*[-+]?\d*\.?\d+(?:deg|rad|turn)?\s*,\s*[-+]?\d*\.?\d+%\s*,\s*[-+]?\d*\.?\d+%(?:\s*,\s*(?:[-+]?\d*\.?\d+|var\([^)]+\)))?\s*\))/gm;
const CSS_VAR_USAGE_PATTERN = /var\(\s*(--[a-zA-Z0-9_-]+)/g;
@@ -80,6 +143,8 @@ function parseArgs(argv) {
reportJson: null,
baselinePath: undefined,
noBaseline: false,
+ packageContracts: [],
+ excludePaths: [],
top: 15,
budget: 120,
};
@@ -110,6 +175,30 @@ function parseArgs(argv) {
}
} else if (arg === '--no-baseline') {
options.noBaseline = true;
+ } else if (arg === '--package-contract') {
+ const packageName = argv[++index];
+ if (!packageName) {
+ throw new Error('--package-contract requires a package name');
+ }
+ options.packageContracts.push(packageName);
+ } else if (arg.startsWith('--package-contract=')) {
+ const packageName = arg.slice('--package-contract='.length);
+ if (!packageName) {
+ throw new Error('--package-contract requires a package name');
+ }
+ options.packageContracts.push(packageName);
+ } else if (arg === '--exclude') {
+ const excludePath = argv[++index];
+ if (!excludePath) {
+ throw new Error('--exclude requires a root-relative path');
+ }
+ options.excludePaths.push(excludePath);
+ } else if (arg.startsWith('--exclude=')) {
+ const excludePath = arg.slice('--exclude='.length);
+ if (!excludePath) {
+ throw new Error('--exclude requires a root-relative path');
+ }
+ options.excludePaths.push(excludePath);
} else if (arg === '--root') {
options.root = argv[++index] ?? DEFAULT_ROOT;
} else if (arg === '--top') {
@@ -136,6 +225,9 @@ Options:
--budget Unique app color budget for the summary. Default: 120
--baseline Enforce a theme color governance baseline.
--no-baseline Disable baseline enforcement.
+ --package-contract
+ Treat a declared design-system package as an external CSS variable owner.
+ --exclude Exclude an explicit root-relative file or directory. Repeatable.
--json Print machine-readable JSON instead of text.
--report-json Write the machine-readable report to a file.
`);
@@ -170,6 +262,20 @@ function normalizePath(filePath) {
return filePath.split(path.sep).join('/');
}
+function normalizeRootRelativePath(filePath) {
+ return normalizePath(path.normalize(filePath))
+ .replace(/^\.\//, '')
+ .replace(/\/$/, '');
+}
+
+function isExplicitlyExcluded(rootRelativePath, excludePaths) {
+ const normalizedPath = normalizeRootRelativePath(rootRelativePath);
+ return excludePaths.some((excludePath) => {
+ const normalizedExclude = normalizeRootRelativePath(excludePath);
+ return normalizedPath === normalizedExclude || normalizedPath.startsWith(`${normalizedExclude}/`);
+ });
+}
+
function isAuditTestFile(relativePath) {
return (
/(^|\/)__tests__\//.test(relativePath)
@@ -181,6 +287,7 @@ function isGeneratedBuildArtifact(rootRelativePath) {
return (
rootRelativePath === 'generated/version.ts'
|| rootRelativePath === 'generated/version-injection.html'
+ || rootRelativePath.startsWith('public/monaco-editor/')
);
}
@@ -214,14 +321,22 @@ function isGeneratedWidgetAppearancePayloadFile(relativePath) {
function collectGeneratedWidgetPayloadVarNames(content) {
const namesBlock = /export const WIDGET_APPEARANCE_VARIABLE_NAMES = \[([\s\S]*?)\] as const;/.exec(content)?.[1];
- if (!namesBlock) {
- throw new Error('Unable to parse WIDGET_APPEARANCE_VARIABLE_NAMES; refusing to audit a partial payload contract.');
+ if (namesBlock) {
+ const names = collectMatches(namesBlock, CSS_VAR_LITERAL_PATTERN).map(match => match[1]);
+ if (names.length === 0) {
+ throw new Error('WIDGET_APPEARANCE_VARIABLE_NAMES must not be empty.');
+ }
+ return names;
}
- const names = collectMatches(namesBlock, CSS_VAR_LITERAL_PATTERN).map(match => match[1]);
- if (names.length === 0) {
- throw new Error('WIDGET_APPEARANCE_VARIABLE_NAMES must not be empty.');
+
+ if (/Object\.values\(themeCssVariables\)/.test(content)) {
+ const themeContract = PACKAGE_CSS_VAR_DEFINITION_CONTRACTS.find(
+ contract => contract.packageName === '@bitfun/theme-bitfun',
+ );
+ if (themeContract?.variables.length) return [...themeContract.variables];
}
- return names;
+
+ throw new Error('Unable to parse WIDGET_APPEARANCE_VARIABLE_NAMES or resolve it from the canonical theme contract.');
}
function pathMatchesPart(relativePath, pathPart) {
@@ -229,6 +344,7 @@ function pathMatchesPart(relativePath, pathPart) {
const normalizedPart = pathPart.toLowerCase();
return (
normalizedPath === normalizedPart
+ || normalizedPath.endsWith(`/${normalizedPart}`)
|| normalizedPath.startsWith(`${normalizedPart}/`)
|| normalizedPath.startsWith(`${normalizedPart}.`)
|| normalizedPath.includes(`/${normalizedPart}/`)
@@ -238,7 +354,8 @@ function pathMatchesPart(relativePath, pathPart) {
function getColorDomain(relativePath) {
const rule = COLOR_DOMAIN_RULES.find(entry => (
- entry.pathParts.some(part => pathMatchesPart(relativePath, part))
+ (!entry.extensions || entry.extensions.includes(path.extname(relativePath).toLowerCase()))
+ && entry.pathParts.some(part => pathMatchesPart(relativePath, part))
));
return rule?.key ?? 'appUi';
}
@@ -258,6 +375,65 @@ function collectMatches(content, pattern) {
return Array.from(content.matchAll(pattern));
}
+function collectNamedColorValues(content, relativePath) {
+ const colors = [];
+ const extension = path.extname(relativePath).toLowerCase();
+
+ if (STYLE_SOURCE_EXTENSIONS.has(extension)) {
+ for (const declaration of collectMatches(content, CSS_DECLARATION_PATTERN)) {
+ if (declaration[1].toLowerCase() === 'content') continue;
+ const valueWithoutUrls = declaration[2].replace(/url\((?:"[^"]*"|'[^']*'|[^)]*)\)/gi, ' ');
+ for (const match of collectMatches(valueWithoutUrls, CSS_NAMED_COLOR_PATTERN)) {
+ colors.push(match[1].toLowerCase());
+ }
+ }
+ }
+
+ if (STYLE_SOURCE_EXTENSIONS.has(extension) || MARKUP_SOURCE_EXTENSIONS.has(extension)) {
+ for (const match of collectMatches(content, CSS_COLOR_ATTRIBUTE_PATTERN)) {
+ colors.push(match[1].toLowerCase());
+ }
+ }
+
+ if (!STYLE_SOURCE_EXTENSIONS.has(extension) && !MARKUP_SOURCE_EXTENSIONS.has(extension)) {
+ for (const match of collectMatches(content, SCRIPT_COLOR_VALUE_PATTERN)) {
+ colors.push(match[1].toLowerCase());
+ }
+ }
+
+ return colors;
+}
+
+function collectRawRgbChannelValues(content) {
+ return collectMatches(content, RAW_RGB_CHANNEL_DEFINITION_PATTERN).map((match) => {
+ const channels = match[1].split(',').map(channel => Number(channel.trim()));
+ return `rgb(${channels.join(', ')})`;
+ });
+}
+
+function collectColorValues(content, relativePath) {
+ return [
+ ...collectMatches(content, COLOR_PATTERN).map(match => match[0]),
+ ...collectNamedColorValues(content, relativePath),
+ ...collectRawRgbChannelValues(content),
+ ];
+}
+
+function collectImportedPackageNames(files, cwd) {
+ const packageNames = new Set();
+ for (const file of files) {
+ const relativePath = normalizePath(path.relative(cwd, file));
+ const content = createAuditContent(fs.readFileSync(file, 'utf8'), relativePath);
+ for (const contract of PACKAGE_CSS_VAR_IMPORT_CONTRACTS) {
+ if (!content.includes(contract.specifier)) continue;
+ for (const packageName of contract.packageNames) {
+ packageNames.add(packageName);
+ }
+ }
+ }
+ return packageNames;
+}
+
function contractOwnerMatchesRoot(contract, rootRelativePath) {
return String(contract.owner ?? '')
.split(';')
@@ -442,13 +618,19 @@ function stripCommentsForAudit(content, { stripLineComments = true } = {}) {
}
function createAuditContent(content, relativePath) {
- return stripCommentsForAudit(content, {
+ const withoutComments = stripCommentsForAudit(content, {
stripLineComments: !relativePath.endsWith('.css'),
});
+ return withoutComments.replace(/(?:x[0-9a-f]+|\d+);/gi, match => ' '.repeat(match.length));
}
function parseColor(color) {
const trimmed = color.trim().toLowerCase();
+ const named = COMMON_NAMED_COLOR_RGB.get(trimmed);
+ if (named) {
+ return { r: named[0], g: named[1], b: named[2], a: 1 };
+ }
+
const hex = /^#([0-9a-f]{3,8})$/.exec(trimmed);
if (hex) {
const raw = hex[1];
@@ -782,12 +964,25 @@ function audit(options) {
!isAuditTestFile(entry.relativePath)
&& isGeneratedBuildArtifact(entry.rootRelativePath)
));
+ const ignoredExplicitFiles = fileEntries.filter(entry => (
+ !isAuditTestFile(entry.relativePath)
+ && !isGeneratedBuildArtifact(entry.rootRelativePath)
+ && isExplicitlyExcluded(entry.rootRelativePath, options.excludePaths)
+ ));
const auditedFiles = fileEntries
.filter(entry => (
!isAuditTestFile(entry.relativePath)
&& !isGeneratedBuildArtifact(entry.rootRelativePath)
+ && !isExplicitlyExcluded(entry.rootRelativePath, options.excludePaths)
))
.map(entry => entry.file);
+ const importedPackageNames = collectImportedPackageNames(auditedFiles, cwd);
+ for (const packageName of options.packageContracts) {
+ if (!PACKAGE_CSS_VAR_DEFINITION_CONTRACTS.some(contract => contract.packageName === packageName)) {
+ throw new Error(`Unknown package CSS variable contract: ${packageName}`);
+ }
+ importedPackageNames.add(packageName);
+ }
const tokenAliasDefinitionsByColorKey = collectTokenAliasDefinitions(auditedFiles, cwd);
const colorCounts = new Map();
@@ -829,7 +1024,7 @@ function audit(options) {
const tokenFile = isTokenFile(relativePath);
const exceptionFile = isExceptionFile(relativePath);
const colorDomain = getColorDomain(relativePath);
- const colors = collectMatches(content, COLOR_PATTERN).map(match => match[0]);
+ const colors = collectColorValues(content, relativePath);
if (colors.length > 0) {
fileColorCounts.set(relativePath, colors.length);
@@ -934,14 +1129,13 @@ function audit(options) {
}
}
- if (checksFullThemeSourceRoot) {
- for (const contract of PACKAGE_CSS_VAR_DEFINITION_CONTRACTS) {
- for (const name of contract.variables) {
- incrementMap(varDefinitionCounts, name);
- addToSetMap(varDefinitionKinds, name, 'package-contract');
- addToSetMap(varDefinitionFiles, name, contract.owner);
- contractVarDefinitions.add(name);
- }
+ for (const contract of PACKAGE_CSS_VAR_DEFINITION_CONTRACTS) {
+ if (!importedPackageNames.has(contract.packageName)) continue;
+ for (const name of contract.variables) {
+ incrementMap(varDefinitionCounts, name);
+ addToSetMap(varDefinitionKinds, name, 'package-contract');
+ addToSetMap(varDefinitionFiles, name, contract.owner);
+ contractVarDefinitions.add(name);
}
}
@@ -1043,6 +1237,7 @@ function audit(options) {
.filter(([name]) => (
runtimeContractVarDefinitions.has(name)
&& !staticContractVarDefinitions.has(name)
+ && !getDefinitionKinds(name).includes('package-contract')
&& !fallbackTokenCounts.has(name)
))
.map(([key, count]) => ({
@@ -1205,6 +1400,7 @@ function audit(options) {
definitionKind: getExplicitDefinitionKind(key),
files: Array.from(generatedWidgetPayloadVarFiles.get(key) ?? []).sort().slice(0, 5),
}));
+ const hasGeneratedWidgetPayloadContract = generatedWidgetPayloadVars.length > 0;
const generatedWidgetPayloadCompatibilityAliases = generatedWidgetPayloadVars
.map(entry => {
const contract = resolveCompatibilityAliasContract(entry.key);
@@ -1266,6 +1462,21 @@ function audit(options) {
.filter(entry => !entry.definitionKind)
.sort((a, b) => a.key.localeCompare(b.key));
const generatedWidgetPayloadVarNames = new Set(generatedWidgetPayloadVars.map(entry => entry.key));
+ const canonicalThemeVariableNames = new Set(
+ PACKAGE_CSS_VAR_DEFINITION_CONTRACTS.find(
+ contract => contract.packageName === '@bitfun/theme-bitfun',
+ )?.variables ?? [],
+ );
+ const generatedWidgetPayloadMissingCanonicalThemeVars = hasGeneratedWidgetPayloadContract
+ ? [...canonicalThemeVariableNames]
+ .filter(name => !generatedWidgetPayloadVarNames.has(name))
+ .sort()
+ : [];
+ const generatedWidgetPayloadNonCanonicalVars = hasGeneratedWidgetPayloadContract
+ ? [...generatedWidgetPayloadVarNames]
+ .filter(name => !canonicalThemeVariableNames.has(name))
+ .sort()
+ : [];
const generatedWidgetPayloadMissingCompatibilityCanonicals = [
...generatedWidgetPayloadCompatibilityAliases,
...generatedWidgetPayloadCompatibilityFamilies,
@@ -1360,8 +1571,14 @@ function audit(options) {
filesScanned: auditedFiles.length,
ignoredTestFiles: ignoredTestFiles.length,
ignoredGeneratedFiles: ignoredGeneratedFiles.length,
+ ignoredExplicitFiles: ignoredExplicitFiles.length,
+ explicitExclusions: options.excludePaths.map(normalizeRootRelativePath).sort(),
filesWithColors: fileColorCounts.size,
colorOccurrences,
+ packageCssContracts: {
+ importedPackages: [...importedPackageNames].sort(),
+ importedPackageUnique: importedPackageNames.size,
+ },
uniqueColors: colorCounts.size,
colorScopes: {
appUi: {
@@ -1418,8 +1635,11 @@ function audit(options) {
families: compatibilityAliasFamilyEntries,
},
generatedWidgetPayload: {
+ present: hasGeneratedWidgetPayloadContract,
varUnique: generatedWidgetPayloadVars.length,
occurrences: generatedWidgetPayloadVars.reduce((total, entry) => total + entry.count, 0),
+ missingCanonicalThemeUnique: generatedWidgetPayloadMissingCanonicalThemeVars.length,
+ nonCanonicalUnique: generatedWidgetPayloadNonCanonicalVars.length,
undefinedUnique: generatedWidgetPayloadUndefinedVars.length,
compatibilityAliasUnique: generatedWidgetPayloadCompatibilityAliases.length,
compatibilityAliasOccurrences: generatedWidgetPayloadCompatibilityAliases.reduce(
@@ -1442,6 +1662,8 @@ function audit(options) {
topCompatibilityFamilies: generatedWidgetPayloadCompatibilityFamilies.slice(0, options.top),
externalOnlyCompatibility: generatedWidgetPayloadExternalOnlyCompatibility.slice(0, REPORT_ROW_LIMIT),
undefinedVars: generatedWidgetPayloadUndefinedVars.slice(0, REPORT_ROW_LIMIT),
+ missingCanonicalThemeVars: generatedWidgetPayloadMissingCanonicalThemeVars.slice(0, REPORT_ROW_LIMIT),
+ nonCanonicalVars: generatedWidgetPayloadNonCanonicalVars.slice(0, REPORT_ROW_LIMIT),
missingCompatibilityCanonicals: generatedWidgetPayloadMissingCompatibilityCanonicals.slice(0, REPORT_ROW_LIMIT),
unexportedCompatibilityCanonicals: generatedWidgetPayloadUnexportedCompatibilityCanonicals.slice(
0,
@@ -1524,6 +1746,7 @@ function printText(report) {
console.log(`Files scanned: ${report.filesScanned}`);
console.log(`Ignored test files: ${report.ignoredTestFiles}`);
console.log(`Ignored generated files: ${report.ignoredGeneratedFiles}`);
+ console.log(`Ignored explicitly excluded files: ${report.ignoredExplicitFiles}`);
console.log(`Files with colors: ${report.filesWithColors}`);
console.log(`Color occurrences: ${report.colorOccurrences}`);
console.log(`Unique colors: ${report.uniqueColors}`);
@@ -1547,6 +1770,8 @@ function printText(report) {
);
console.log(
`Generated widget payload: vars=${report.generatedWidgetPayload.varUnique}, ` +
+ `missingCanonicalTheme=${report.generatedWidgetPayload.missingCanonicalThemeUnique}, ` +
+ `nonCanonical=${report.generatedWidgetPayload.nonCanonicalUnique}, ` +
`undefined=${report.generatedWidgetPayload.undefinedUnique}, ` +
`compatAliases=${report.generatedWidgetPayload.compatibilityAliasUnique}, ` +
`compatAliasFamilies=${report.generatedWidgetPayload.compatibilityAliasFamilyUnique}, ` +
diff --git a/scripts/audit-theme-colors.test.mjs b/scripts/audit-theme-colors.test.mjs
index f988791977..4e27a81f7b 100644
--- a/scripts/audit-theme-colors.test.mjs
+++ b/scripts/audit-theme-colors.test.mjs
@@ -20,11 +20,12 @@ import {
const root = process.cwd();
const SOURCE_OWNER_ROOTS = [
'BitFun-Installer/src',
+ 'src/apps/mobile/design-system/preview',
'src/mobile-web/src',
- 'src/web-ui/src',
+ 'src/web-ui',
];
const NEAR_PAIR_DECISION_AUDIT_ROOTS = [
- { root: 'src/web-ui/src', args: ['--json', '--no-baseline', '--top', '0'] },
+ { root: 'src/web-ui', args: ['--json', '--no-baseline', '--top', '0'] },
{ root: 'src/mobile-web/src', args: ['--root', 'src/mobile-web/src', '--json', '--no-baseline', '--top', '0'] },
{ root: 'BitFun-Installer/src', args: ['--root', 'BitFun-Installer/src', '--json', '--no-baseline', '--top', '0'] },
];
@@ -114,6 +115,10 @@ test('theme CSS var contract registry is explicit and non-overlapping', () => {
assert.equal(typeof rule.label, 'string');
assert.ok(rule.label.trim(), `${rule.key} must have a label`);
assert.ok(Array.isArray(rule.pathParts) && rule.pathParts.length > 0, `${rule.key} must have path parts`);
+ if (rule.extensions !== undefined) {
+ assert.ok(Array.isArray(rule.extensions) && rule.extensions.length > 0, `${rule.key} extensions must be non-empty`);
+ assert.ok(rule.extensions.every(extension => /^\.[a-z0-9]+$/.test(extension)), `${rule.key} extensions must be normalized`);
+ }
}
const dynamicPrefixes = new Set(DYNAMIC_VAR_FAMILY_CONTRACTS.map(contract => contract.prefix));
@@ -163,7 +168,7 @@ test('theme CSS var contract registry is explicit and non-overlapping', () => {
'every specialized color domain must have an owner contract',
);
for (const contract of COLOR_DOMAIN_CONTRACTS) {
- assert.ok(contract.owner.includes('src/web-ui/src/'), `${contract.key} must name a source owner`);
+ assert.ok(contractOwnerHasKnownSource(contract.owner), `${contract.key} must name a source owner`);
assert.ok(contract.reason.trim().length >= 30, `${contract.key} must explain why the domain exists`);
assert.ok(contract.mergePolicy.trim().length >= 30, `${contract.key} must define a merge policy`);
}
@@ -321,6 +326,7 @@ test('repository specialized near color pairs have explicit decisions', () => {
test('generated widget iframe has no compatibility alias module or contracts', () => {
assert.equal(TOKEN_COMPATIBILITY_ALIAS_CONTRACTS.length, 0);
assert.equal(TOKEN_COMPATIBILITY_ALIAS_FAMILY_CONTRACTS.length, 0);
+ assert.equal(SURFACE_TOKEN_RENAME_CONTRACTS.length, 0);
assert.equal(
fs.existsSync(path.join(root, 'src/web-ui/src/tools/generative-widget/appearancePayloadCompatibility.ts')),
false,
@@ -336,7 +342,7 @@ test('theme color audit emits scoped machine-readable reports', (t) => {
'}',
'',
].join('\n'),
- 'infrastructure/appearance/adapters/CssTokenAppearanceAdapter.ts': [
+ 'infrastructure/appearance/adapters/ThemeTokenAppearanceAdapter.ts': [
"document.documentElement.style.setProperty('--runtime-only', '#333333');",
'',
].join('\n'),
@@ -418,12 +424,14 @@ test('theme color audit reports static contract token external consumption', (t)
);
});
-test('theme color audit reports deprecated surface-local token names', (t) => {
+test('theme color audit resolves canonical variables from imported package CSS contracts', (t) => {
const { dir, sourceRoot } = createFixture({
- 'tools/editor/meditor/components/TiptapEditor.scss': [
- '.m-editor-tiptap {',
- ' --m-editor-highlight-rgb: var(--private-markdown-editor-highlight-rgb);',
- ' background: rgba(var(--m-editor-highlight-rgb), 0.15);',
+ 'main.tsx': "import '@bitfun/theme-bitfun/default.css';\n",
+ 'app/App.scss': [
+ '.app {',
+ ' color: var(--bf-color-content-primary);',
+ ' background: var(--bf-color-surface-canvas);',
+ ' padding: var(--bf-space-1);',
'}',
'',
].join('\n'),
@@ -434,14 +442,29 @@ test('theme color audit reports deprecated surface-local token names', (t) => {
assert.equal(result.status, 0, result.stderr || result.stdout);
const report = JSON.parse(result.stdout);
- assert.equal(report.surfaceTokenRenames.activeUnique, 1);
- assert.equal(report.surfaceTokenRenames.activeOccurrences, 2);
- assert.deepEqual(
- report.surfaceTokenRenames.active.map(row => [row.key, row.canonical, row.definitionCount, row.usageCount]),
- [
- ['--m-editor-highlight-rgb', '--private-markdown-editor-highlight-rgb', 1, 1],
- ],
- );
+ assert.deepEqual(report.packageCssContracts.importedPackages, [
+ '@bitfun/design-tokens',
+ '@bitfun/theme-bitfun',
+ ]);
+ assert.equal(report.cssVarDefinitions.unresolvedUnique, 0);
+ assert.equal(report.cssVarDefinitions.unresolvedRequiredUnique, 0);
+});
+
+test('theme color audit does not require a widget payload on surfaces without that contract', (t) => {
+ const { dir, sourceRoot } = createFixture({
+ 'main.tsx': "import '@bitfun/theme-bitfun/default.css';\n",
+ 'app/App.scss': '.app { color: var(--bf-color-content-primary); }\n',
+ });
+ t.after(() => fs.rmSync(dir, { recursive: true, force: true }));
+
+ const result = runAudit(['--root', sourceRoot, '--json', '--no-baseline']);
+ assert.equal(result.status, 0, result.stderr || result.stdout);
+
+ const report = JSON.parse(result.stdout);
+ assert.equal(report.generatedWidgetPayload.present, false);
+ assert.equal(report.generatedWidgetPayload.missingCanonicalThemeUnique, 0);
+ assert.equal(report.generatedWidgetPayload.nonCanonicalUnique, 0);
+ assert.equal(report.generatedWidgetPayload.undefinedUnique, 0);
});
test('theme color audit counts only the generated widget variable contract', (t) => {
@@ -594,6 +617,95 @@ test('theme color audit ignores comment-only color-like text', (t) => {
assert.equal(report.colorDomainScopes.appUi.uniqueColors, 1);
});
+test('theme color audit counts named CSS colors and raw RGB channel variables without selector or comment noise', (t) => {
+ const { dir, sourceRoot } = createFixture({
+ 'app/App.scss': [
+ '/* white and black are documentation here, not values. */',
+ '.app[data-tone="red"] {',
+ ' --private-brand-rgb: 12, 34, 56;',
+ ' color: white;',
+ ' box-shadow: 0 0 0 1px black;',
+ '}',
+ '.app::before { content: "blue"; }',
+ '.search {',
+ ' mask: url("data:image/svg+xml;utf8,");',
+ '}',
+ '',
+ ].join('\n'),
+ 'app/style.ts': "export const style = { color: 'blue' };\n",
+ });
+ t.after(() => fs.rmSync(dir, { recursive: true, force: true }));
+
+ const result = runAudit(['--root', sourceRoot, '--json', '--no-baseline']);
+ assert.equal(result.status, 0, result.stderr || result.stdout);
+
+ const report = JSON.parse(result.stdout);
+ assert.equal(report.colorOccurrences, 5);
+ assert.equal(report.uniqueColors, 5);
+ assert.deepEqual(
+ new Set(report.topColors.map(entry => entry.key)),
+ new Set(['rgb(12, 34, 56)', 'white', 'black', 'red', 'blue']),
+ );
+ assert.equal(report.colorDomainScopes.appUi.occurrences, 5);
+});
+
+test('theme color audit ignores numeric character references in SVG metadata', (t) => {
+ const { dir, sourceRoot } = createFixture({
+ 'app/assets/icon.svg': [
+ '',
+ '',
+ ].join('\n'),
+ });
+ t.after(() => fs.rmSync(dir, { recursive: true, force: true }));
+
+ const result = runAudit(['--root', sourceRoot, '--json', '--no-baseline']);
+ assert.equal(result.status, 0, result.stderr || result.stdout);
+
+ const report = JSON.parse(result.stdout);
+ assert.equal(report.colorOccurrences, 0);
+ assert.equal(report.colorDomainScopes.assetMetadata.occurrences, 0);
+});
+
+test('theme color audit does not exempt executable styles merely because their path contains assets', (t) => {
+ const { dir, sourceRoot } = createFixture({
+ 'app/assets/embedded-app/style.css': '.panel { color: #123456; }\n',
+ 'app/assets/brand.svg': '\n',
+ });
+ t.after(() => fs.rmSync(dir, { recursive: true, force: true }));
+
+ const result = runAudit(['--root', sourceRoot, '--json', '--no-baseline']);
+ assert.equal(result.status, 0, result.stderr || result.stdout);
+
+ const report = JSON.parse(result.stdout);
+ assert.equal(report.colorDomainScopes.appUi.occurrences, 1);
+ assert.equal(report.colorDomainScopes.assetMetadata.occurrences, 1);
+});
+
+test('theme color audit can resolve peer-owned public package variables explicitly', (t) => {
+ const { dir, sourceRoot } = createFixture({
+ 'components/Button.css': '.button { color: var(--bf-color-content-primary); padding: var(--bf-space-2); }\n',
+ });
+ t.after(() => fs.rmSync(dir, { recursive: true, force: true }));
+
+ const result = runAudit([
+ '--root', sourceRoot,
+ '--package-contract', '@bitfun/design-tokens',
+ '--package-contract', '@bitfun/theme-bitfun',
+ '--json',
+ '--no-baseline',
+ ]);
+ assert.equal(result.status, 0, result.stderr || result.stdout);
+
+ const report = JSON.parse(result.stdout);
+ assert.equal(report.cssVarDefinitions.unresolvedUnique, 0);
+ assert.deepEqual(
+ report.packageCssContracts.importedPackages,
+ ['@bitfun/design-tokens', '@bitfun/theme-bitfun'],
+ );
+});
+
test('theme color audit keeps template literal and expression color values', (t) => {
const { dir, sourceRoot } = createFixture({
'app/App.tsx': [
@@ -641,7 +753,7 @@ test('theme color audit counts full CSS var governance debt before row truncatio
(_, index) => `.loose-${index} { color: var(--loose-${index}); }`,
);
const { dir, sourceRoot } = createFixture({
- 'infrastructure/appearance/adapters/CssTokenAppearanceAdapter.ts': `${runtimeDefinitions.join('\n')}\n`,
+ 'infrastructure/appearance/adapters/ThemeTokenAppearanceAdapter.ts': `${runtimeDefinitions.join('\n')}\n`,
'app/App.scss': `${missingRules.join('\n')}\n${fallbackRules.join('\n')}\n${runtimeRules.join('\n')}\n`,
'app/LooseVar.tsx': [
'export function LooseVar() {',
@@ -854,7 +966,7 @@ test('theme color audit fails when fallback tokens lack a boundary contract', (t
test('theme color audit requires dynamic CSS var families to be registered', (t) => {
const { dir, sourceRoot } = createFixture({
- 'infrastructure/appearance/adapters/CssTokenAppearanceAdapter.ts': [
+ 'infrastructure/appearance/adapters/ThemeTokenAppearanceAdapter.ts': [
"for (const [key, value] of Object.entries(theme.extra)) {",
" document.documentElement.style.setProperty(`--unregistered-${key}`, value);",
'}',
@@ -881,7 +993,7 @@ test('theme color audit requires dynamic CSS var families to be registered', (t)
test('theme color audit accepts registered dynamic CSS var families', (t) => {
const { dir, sourceRoot } = createFixture({
- 'infrastructure/appearance/adapters/CssTokenAppearanceAdapter.ts': [
+ 'infrastructure/appearance/adapters/ThemeTokenAppearanceAdapter.ts': [
"for (const [key, value] of Object.entries(fontSizeTokens)) {",
" document.documentElement.style.setProperty(`--bf-font-size-${key}`, value);",
'}',
@@ -909,7 +1021,7 @@ test('theme color audit requires exact exports for dynamic-family CSS var usages
'}',
'',
].join('\n'),
- 'infrastructure/appearance/adapters/CssTokenAppearanceAdapter.ts': [
+ 'infrastructure/appearance/adapters/ThemeTokenAppearanceAdapter.ts': [
"for (const [key, value] of Object.entries(theme.colors.purple)) {",
" document.documentElement.style.setProperty(`--bf-appearance-token-color-purple-${key}`, value);",
'}',
@@ -1020,3 +1132,25 @@ test('theme color audit fails stale non-contract var allowlist entries', (t) =>
/nonContractDynamicInputs allowlist entry --removed-var is stale/,
);
});
+
+test('theme color audit excludes only explicitly named root-relative paths', (t) => {
+ const { dir, sourceRoot } = createFixture({
+ 'app/App.scss': '.app { color: var(--bf-color-content-primary); }\n',
+ 'generated/palette.css': '.generated { color: #ff00ff; }\n',
+ });
+ t.after(() => fs.rmSync(dir, { recursive: true, force: true }));
+
+ const result = runAudit([
+ '--root', sourceRoot,
+ '--exclude', 'generated',
+ '--package-contract', '@bitfun/theme-bitfun',
+ '--json',
+ '--no-baseline',
+ ]);
+ assert.equal(result.status, 0, result.stderr || result.stdout);
+ const report = JSON.parse(result.stdout);
+ assert.equal(report.filesScanned, 1);
+ assert.equal(report.ignoredExplicitFiles, 1);
+ assert.deepEqual(report.explicitExclusions, ['generated']);
+ assert.equal(report.colorScopes.appUi.occurrences, 0);
+});
diff --git a/scripts/frontend-color-surface-registry.json b/scripts/frontend-color-surface-registry.json
new file mode 100644
index 0000000000..04ac73f09d
--- /dev/null
+++ b/scripts/frontend-color-surface-registry.json
@@ -0,0 +1,481 @@
+{
+ "version": 1,
+ "description": "Authoritative registry for every BitFun frontend color surface, its canonical token owner, narrowly scoped specialized palette owners, and non-product artifacts excluded from ordinary UI governance.",
+ "contracts": {
+ "webSystem": "design-system/packages/design-tokens/src/system.tokens.json",
+ "webTheme": "design-system/packages/theme-bitfun/src/light.tokens.json",
+ "miniappAppearance": "src/shared/miniapp-appearance/contract.json",
+ "nativeMobile": "src/apps/mobile/design-system/tokens/mobile-tokens.json"
+ },
+ "discovery": {
+ "miniappParents": [
+ "MiniApp/Demo",
+ "src/crates/contracts/product-domains/src/miniapp/builtin/assets",
+ "src/crates/assembly/core/builtin_skills/miniapp-dev/references/examples"
+ ]
+ },
+ "surfaces": [
+ {
+ "id": "design-system-token-owner",
+ "label": "Design system token authoring",
+ "kind": "contract-owner",
+ "owner": "@bitfun/design-tokens and @bitfun/theme-bitfun",
+ "roots": [
+ "design-system/packages/design-tokens/src",
+ "design-system/packages/theme-bitfun/src"
+ ]
+ },
+ {
+ "id": "web-ui",
+ "label": "Web UI",
+ "kind": "canonical-web",
+ "owner": "@bitfun/theme-bitfun plus Web UI Appearance theme-tokens",
+ "root": "src/web-ui",
+ "audit": {
+ "engine": "theme",
+ "baseline": "scripts/theme-color-governance-baseline.json"
+ }
+ },
+ {
+ "id": "design-system-ui",
+ "label": "Public design-system UI package",
+ "kind": "canonical-web",
+ "owner": "@bitfun/ui consuming peer-owned canonical tokens",
+ "root": "design-system/packages/ui",
+ "audit": {
+ "engine": "theme",
+ "baseline": "scripts/theme-color-governance-baseline.design-system-ui.json",
+ "packageContracts": ["@bitfun/design-tokens", "@bitfun/theme-bitfun"]
+ }
+ },
+ {
+ "id": "design-lab",
+ "label": "Design Lab",
+ "kind": "canonical-web",
+ "owner": "@bitfun/theme-bitfun",
+ "root": "design-system/apps/design-lab",
+ "audit": {
+ "engine": "theme",
+ "baseline": "scripts/theme-color-governance-baseline.design-lab.json"
+ }
+ },
+ {
+ "id": "miniapp-market",
+ "label": "Mini App Market",
+ "kind": "canonical-web",
+ "owner": "@bitfun/theme-bitfun",
+ "root": "src/miniapp-market-web",
+ "audit": {
+ "engine": "theme",
+ "baseline": "scripts/theme-color-governance-baseline.miniapp-market.json"
+ }
+ },
+ {
+ "id": "skin-market",
+ "label": "Skin Market",
+ "kind": "canonical-web",
+ "owner": "@bitfun/theme-bitfun",
+ "root": "src/skin-market-web",
+ "audit": {
+ "engine": "theme",
+ "baseline": "scripts/theme-color-governance-baseline.skin-market.json"
+ }
+ },
+ {
+ "id": "website",
+ "label": "Public website",
+ "kind": "canonical-web",
+ "owner": "@bitfun/theme-bitfun",
+ "root": "website",
+ "audit": {
+ "engine": "theme",
+ "baseline": "scripts/theme-color-governance-baseline.website.json"
+ }
+ },
+ {
+ "id": "mobile-web",
+ "label": "Mobile Web and Remote Control",
+ "kind": "canonical-web",
+ "owner": "@bitfun/theme-bitfun",
+ "root": "src/mobile-web",
+ "audit": {
+ "engine": "theme",
+ "baseline": "scripts/theme-color-governance-baseline.mobile-web.json"
+ }
+ },
+ {
+ "id": "installer",
+ "label": "BitFun Installer",
+ "kind": "canonical-web",
+ "owner": "@bitfun/theme-bitfun with the installer preset owner",
+ "root": "BitFun-Installer",
+ "audit": {
+ "engine": "theme",
+ "baseline": "scripts/theme-color-governance-baseline.installer.json"
+ }
+ },
+ {
+ "id": "desktop-bootstrap",
+ "label": "Desktop pre-JavaScript bootstrap pages",
+ "kind": "canonical-web",
+ "owner": "generated @bitfun/theme-bitfun bootstrap projection",
+ "root": "src/apps/desktop/bootstrap-ui",
+ "audit": {
+ "engine": "theme",
+ "policy": "canonical-ui-zero",
+ "packageContracts": ["@bitfun/design-tokens", "@bitfun/theme-bitfun"]
+ }
+ },
+ {
+ "id": "mobile-design-preview",
+ "label": "Native mobile comparison preview",
+ "kind": "canonical-web",
+ "owner": "canonical web tokens for chrome and generated native mobile tokens for device content",
+ "root": "src/apps/mobile/design-system/preview",
+ "audit": {
+ "engine": "theme",
+ "policy": "canonical-ui-zero",
+ "packageContracts": ["@bitfun/design-tokens", "@bitfun/theme-bitfun"],
+ "excludePaths": ["generated"]
+ }
+ },
+ {
+ "id": "cli",
+ "label": "CLI and TUI",
+ "kind": "terminal",
+ "owner": "src/apps/cli/themes/presets and the terminal theme adapter",
+ "root": "src/apps/cli",
+ "audit": {
+ "engine": "cli",
+ "baseline": "scripts/theme-color-governance-baseline.cli.json"
+ }
+ },
+ {
+ "id": "native-android",
+ "label": "Native Android",
+ "kind": "native-mobile",
+ "owner": "src/apps/mobile/design-system/tokens/mobile-tokens.json",
+ "root": "src/apps/mobile/android/app/src/main/kotlin",
+ "audit": {
+ "engine": "native",
+ "platform": "android",
+ "extensions": [".kt"],
+ "excludePaths": [
+ "com/bitfun/mobile/app/ui/theme/generated",
+ "com/bitfun/mobile/app/ui/preview/generated"
+ ]
+ }
+ },
+ {
+ "id": "native-ios",
+ "label": "Native iOS",
+ "kind": "native-mobile",
+ "owner": "src/apps/mobile/design-system/tokens/mobile-tokens.json",
+ "root": "src/apps/mobile/ios/BitFun",
+ "audit": {
+ "engine": "native",
+ "platform": "ios",
+ "extensions": [".swift"],
+ "excludeFiles": [
+ "Features/DesignSystem/GeneratedMobileDesignTokens.swift",
+ "Features/DesignSystem/GeneratedMobilePreviewScenarios.swift"
+ ]
+ }
+ },
+ {
+ "id": "native-harmonyos",
+ "label": "Native HarmonyOS",
+ "kind": "native-mobile",
+ "owner": "src/apps/mobile/design-system/tokens/mobile-tokens.json",
+ "root": "src/apps/mobile/harmonyos/entry/src/main/ets",
+ "audit": {
+ "engine": "native",
+ "platform": "harmonyos",
+ "extensions": [".ets"],
+ "excludePaths": ["generated"]
+ }
+ },
+ {
+ "id": "miniapp-coding-selfie",
+ "label": "Coding Selfie MiniApp",
+ "kind": "miniapp",
+ "owner": "MiniApp public appearance contract",
+ "root": "src/crates/contracts/product-domains/src/miniapp/builtin/assets/coding-selfie",
+ "audit": {
+ "engine": "miniapp",
+ "rawColorOwners": [
+ {
+ "kind": "data-viz",
+ "file": "ui.js",
+ "startMarker": "const LANG_COLORS = [",
+ "endMarker": "];",
+ "reason": "Categorical language-series colors must remain distinguishable and are renderer data, not application chrome."
+ }
+ ]
+ }
+ },
+ {
+ "id": "miniapp-divination",
+ "label": "Daily Divination MiniApp",
+ "kind": "miniapp",
+ "owner": "self-contained bespoke theme",
+ "root": "src/crates/contracts/product-domains/src/miniapp/builtin/assets/divination",
+ "audit": {
+ "engine": "miniapp",
+ "rawColorOwners": [
+ {
+ "kind": "bespoke-theme",
+ "pathPrefixes": ["style.css", "ui.js"],
+ "reason": "The tarot scene is an intentionally self-contained illustrated light/dark theme whose palette is the product content."
+ }
+ ]
+ }
+ },
+ {
+ "id": "miniapp-gomoku",
+ "label": "Gomoku MiniApp",
+ "kind": "miniapp",
+ "owner": "MiniApp public appearance contract",
+ "root": "src/crates/contracts/product-domains/src/miniapp/builtin/assets/gomoku",
+ "audit": {
+ "engine": "miniapp",
+ "rawColorOwners": [
+ {
+ "kind": "game-renderer",
+ "file": "style.css",
+ "linePattern": "^\\s*--g-stone-(?:black|white)(?:-stroke)?\\s*:",
+ "reason": "Stone fills and contrast rims are game-renderer content and must not become reusable UI tokens."
+ }
+ ]
+ }
+ },
+ {
+ "id": "miniapp-ppt-live",
+ "label": "PPT Live MiniApp",
+ "kind": "miniapp",
+ "owner": "MiniApp public appearance contract for editor chrome and slide-renderer ownership for authored content",
+ "root": "src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live",
+ "audit": {
+ "engine": "miniapp",
+ "excludePaths": ["dist"],
+ "rawColorOwners": [
+ {
+ "kind": "slide-renderer",
+ "pathPrefixes": ["src", "test"],
+ "reason": "Slide markup, export fixtures, and presentation authoring palettes are user-content renderer data rather than MiniApp editor chrome."
+ }
+ ]
+ }
+ },
+ {
+ "id": "miniapp-regex-playground",
+ "label": "Regex Playground MiniApp",
+ "kind": "miniapp",
+ "owner": "MiniApp public appearance contract",
+ "root": "src/crates/contracts/product-domains/src/miniapp/builtin/assets/regex-playground",
+ "audit": {
+ "engine": "miniapp"
+ }
+ },
+ {
+ "id": "miniapp-git-graph",
+ "label": "Git Graph MiniApp",
+ "kind": "miniapp",
+ "owner": "MiniApp public appearance contract",
+ "root": "MiniApp/Demo/git-graph",
+ "audit": {
+ "engine": "miniapp",
+ "rawColorOwners": [
+ {
+ "kind": "data-viz",
+ "files": ["source/styles/tokens.css", "source/style.css"],
+ "linePattern": "^\\s*--branch-[5-7]\\s*:",
+ "reason": "The final three branch-lane colors extend the host semantic set for categorical graph separation."
+ }
+ ],
+ "generatedBundles": [
+ {
+ "output": "source/ui.js",
+ "inputs": [
+ "source/ui/state.js",
+ "source/ui/appearance.js",
+ "source/ui/graph/layout.js",
+ "source/ui/graph/renderRowSvg.js",
+ "source/ui/services/gitClient.js",
+ "source/ui/components/contextMenu.js",
+ "source/ui/components/modal.js",
+ "source/ui/components/findWidget.js",
+ "source/ui/panels/remotePanel.js",
+ "source/ui/panels/detailPanel.js",
+ "source/ui/main.js",
+ "source/ui/bootstrap.js"
+ ]
+ },
+ {
+ "output": "source/style.css",
+ "inputs": [
+ "source/styles/tokens.css",
+ "source/styles/layout.css",
+ "source/styles/graph.css",
+ "source/styles/detail-panel.css",
+ "source/styles/overlay.css"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "id": "miniapp-icon-design-system",
+ "label": "Icon Design System MiniApp",
+ "kind": "miniapp",
+ "owner": "MiniApp public appearance contract",
+ "root": "MiniApp/Demo/icon-design-system",
+ "audit": {
+ "engine": "miniapp"
+ }
+ }
+ ],
+ "mirrors": [
+ {
+ "surfaceId": "miniapp-git-graph",
+ "path": "src/crates/assembly/core/builtin_skills/miniapp-dev/references/examples/demo-git-graph"
+ },
+ {
+ "surfaceId": "miniapp-icon-design-system",
+ "path": "src/crates/assembly/core/builtin_skills/miniapp-dev/references/examples/demo-icon-design-system"
+ },
+ {
+ "surfaceId": "miniapp-coding-selfie",
+ "path": "src/crates/assembly/core/builtin_skills/miniapp-dev/references/examples/builtin-coding-selfie"
+ },
+ {
+ "surfaceId": "miniapp-divination",
+ "path": "src/crates/assembly/core/builtin_skills/miniapp-dev/references/examples/builtin-daily-divination"
+ },
+ {
+ "surfaceId": "miniapp-gomoku",
+ "path": "src/crates/assembly/core/builtin_skills/miniapp-dev/references/examples/builtin-gomoku"
+ },
+ {
+ "surfaceId": "miniapp-regex-playground",
+ "path": "src/crates/assembly/core/builtin_skills/miniapp-dev/references/examples/builtin-regex-playground"
+ }
+ ],
+ "generatedChecks": [
+ {
+ "id": "desktop-appearance-projection",
+ "surfaceIds": ["web-ui", "desktop-bootstrap"],
+ "command": ["node", "scripts/generate-startup-appearance-bootstrap.mjs", "--check"]
+ },
+ {
+ "id": "miniapp-appearance-projection",
+ "surfaceKinds": ["miniapp"],
+ "command": ["node", "scripts/generate-miniapp-appearance-contract.mjs", "--check"]
+ },
+ {
+ "id": "native-mobile-token-projection",
+ "surfaceKinds": ["native-mobile"],
+ "surfaceIds": ["mobile-design-preview"],
+ "command": ["node", "scripts/mobile-ui-design-system.mjs", "--check"]
+ },
+ {
+ "id": "native-mobile-preview-assets",
+ "surfaceKinds": ["native-mobile"],
+ "surfaceIds": ["mobile-design-preview"],
+ "command": ["node", "scripts/mobile-ui-preview.mjs", "--check"]
+ }
+ ],
+ "exclusions": [
+ {
+ "id": "monaco-generated",
+ "path": "src/web-ui/public/monaco-editor",
+ "kind": "generated-third-party",
+ "owner": "Monaco package copy step",
+ "reason": "Vendored editor output is verified by the Monaco asset check and is not BitFun application UI source."
+ },
+ {
+ "id": "relay-static",
+ "path": "src/apps/relay-server/static",
+ "kind": "static-operational-surface",
+ "owner": "Relay server",
+ "reason": "Self-contained relay operational pages do not load the product design-system runtime and are governed by their owning server surface."
+ },
+ {
+ "id": "e2e-fixtures",
+ "path": "tests/e2e/fixtures",
+ "kind": "test-fixture",
+ "owner": "E2E tests",
+ "reason": "Fixture colors describe test input and are never shipped as product UI."
+ },
+ {
+ "id": "diagnostic-report-html",
+ "path": "scripts/request-trace-tools/usage-dashboard.html",
+ "kind": "diagnostic-artifact",
+ "owner": "Request trace tooling",
+ "reason": "The standalone diagnostic report is not a product frontend and has an independent operational lifecycle."
+ },
+ {
+ "id": "ppt-content-source",
+ "path": "src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/src",
+ "kind": "slide-renderer",
+ "owner": "PPT Live slide renderer",
+ "reason": "Presentation content and export palettes are renderer payloads, not editor chrome."
+ },
+ {
+ "id": "ppt-content-tests",
+ "path": "src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/test",
+ "kind": "slide-renderer",
+ "owner": "PPT Live slide renderer tests",
+ "reason": "Expected slide markup colors test renderer fidelity rather than application chrome."
+ },
+ {
+ "id": "ppt-generated-bundle",
+ "path": "src/crates/contracts/product-domains/src/miniapp/builtin/assets/ppt-live/dist",
+ "kind": "generated-output",
+ "owner": "PPT Live build-bitfun.mjs",
+ "reason": "Bundled JavaScript is generated from the registered PPT source owner."
+ },
+ {
+ "id": "android-template-icons",
+ "path": "src/apps/mobile/android/app/src/main/res/drawable",
+ "kind": "native-template-asset",
+ "owner": "Android resource layer",
+ "reason": "Monochrome vector templates are tinted by native semantic tokens at render time."
+ },
+ {
+ "id": "ios-template-icons",
+ "path": "src/apps/mobile/ios/BitFun/Resources.xcassets",
+ "kind": "native-template-asset",
+ "owner": "iOS asset catalog",
+ "reason": "Template images and app metadata are tinted or consumed by the platform asset layer."
+ },
+ {
+ "id": "harmony-template-media",
+ "path": "src/apps/mobile/harmonyos/entry/src/main/resources/base/media",
+ "kind": "native-template-asset",
+ "owner": "HarmonyOS resource layer",
+ "reason": "Template media is tinted by semantic ResourceColor values in the native UI."
+ },
+ {
+ "id": "mobile-preview-generated",
+ "path": "src/apps/mobile/design-system/preview/generated",
+ "kind": "generated-output",
+ "owner": "scripts/mobile-ui-design-system.mjs",
+ "reason": "Preview data is generated from the native mobile token contract and checked for drift."
+ },
+ {
+ "id": "desktop-bootstrap-generated",
+ "path": "src/apps/desktop/src/generated",
+ "kind": "generated-output",
+ "owner": "scripts/generate-startup-appearance-bootstrap.mjs",
+ "reason": "Desktop first-paint theme CSS and manifests are generated from canonical Appearance and theme sources."
+ },
+ {
+ "id": "miniapp-appearance-generated",
+ "path": "src/crates/contracts/product-domains/src/miniapp/generated",
+ "kind": "generated-output",
+ "owner": "scripts/generate-miniapp-appearance-contract.mjs",
+ "reason": "MiniApp first-paint variables are generated from the public projection contract."
+ }
+ ]
+}
diff --git a/scripts/generate-miniapp-appearance-contract.mjs b/scripts/generate-miniapp-appearance-contract.mjs
new file mode 100644
index 0000000000..6a2f3a397d
--- /dev/null
+++ b/scripts/generate-miniapp-appearance-contract.mjs
@@ -0,0 +1,110 @@
+#!/usr/bin/env node
+
+import fs from 'node:fs';
+import path from 'node:path';
+import process from 'node:process';
+import { fileURLToPath, pathToFileURL } from 'node:url';
+
+const repositoryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
+const contractPath = path.join(repositoryRoot, 'src/shared/miniapp-appearance/contract.json');
+const outputPath = path.join(
+ repositoryRoot,
+ 'src/crates/contracts/product-domains/src/miniapp/generated/default_appearance_style.html',
+);
+const themeEntryPath = path.join(repositoryRoot, 'design-system/packages/theme-bitfun/dist/index.js');
+const systemEntryPath = path.join(repositoryRoot, 'design-system/packages/design-tokens/dist/index.js');
+const checkOnly = process.argv.includes('--check');
+
+const contract = JSON.parse(fs.readFileSync(contractPath, 'utf8'));
+const [{ themes, themeCssVariables }, { cssVariables: systemCssVariables, tokens: systemTokens }] = await Promise.all([
+ import(pathToFileURL(themeEntryPath).href),
+ import(pathToFileURL(systemEntryPath).href),
+]);
+
+const themeNamesByCssVariable = invertUnique(themeCssVariables, 'theme');
+const systemNamesByCssVariable = invertUnique(systemCssVariables, 'system');
+validateContract(contract);
+const systemDeclarations = renderDeclarations('system');
+const darkDeclarations = renderDeclarations('theme', 'dark');
+const lightDeclarations = renderDeclarations('theme', 'light');
+const generated = [
+ '',
+ '',
+].join('\n');
+
+const current = fs.existsSync(outputPath) ? normalize(fs.readFileSync(outputPath, 'utf8')) : null;
+if (checkOnly) {
+ if (current !== normalize(generated)) {
+ console.error('[miniapp-appearance] Generated first-paint projection is stale. Run `pnpm run miniapp:appearance:generate`.');
+ process.exit(1);
+ }
+ console.log('[miniapp-appearance] Contract and generated first-paint projection are in sync.');
+} else {
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
+ fs.writeFileSync(outputPath, generated, 'utf8');
+ console.log(`[miniapp-appearance] Wrote ${relative(outputPath)}.`);
+}
+
+function validateContract(value) {
+ if (value?.version !== 1 || !Array.isArray(value.variables) || value.variables.length === 0) {
+ throw new Error('Unsupported or empty MiniApp appearance contract.');
+ }
+ const names = new Set();
+ for (const variable of value.variables) {
+ if (!/^--bitfun-[a-z0-9-]+$/.test(variable.name ?? '')) {
+ throw new Error(`Invalid MiniApp appearance variable: ${String(variable.name)}.`);
+ }
+ if (names.has(variable.name)) throw new Error(`Duplicate MiniApp appearance variable: ${variable.name}.`);
+ names.add(variable.name);
+ if (!['theme', 'system'].includes(variable.kind)) {
+ throw new Error(`Invalid MiniApp appearance variable kind for ${variable.name}.`);
+ }
+ const owners = variable.kind === 'theme' ? themeNamesByCssVariable : systemNamesByCssVariable;
+ if (!owners.has(variable.source)) {
+ throw new Error(`${variable.name} references unknown canonical ${variable.kind} variable ${variable.source}.`);
+ }
+ }
+}
+
+function invertUnique(values, label) {
+ const result = new Map();
+ for (const [name, cssVariable] of Object.entries(values)) {
+ if (result.has(cssVariable)) throw new Error(`Duplicate canonical ${label} CSS variable ${cssVariable}.`);
+ result.set(cssVariable, name);
+ }
+ return result;
+}
+
+function renderDeclarations(kind, mode) {
+ return contract.variables
+ .filter(variable => variable.kind === kind)
+ .map(variable => {
+ const canonicalName = (kind === 'theme' ? themeNamesByCssVariable : systemNamesByCssVariable).get(variable.source);
+ const value = kind === 'theme' ? themes[mode][canonicalName] : systemTokens[canonicalName];
+ if (!['string', 'number'].includes(typeof value)) {
+ throw new Error(`Canonical value for ${variable.source} cannot be serialized into CSS.`);
+ }
+ return ` ${variable.name}: ${String(value)};`;
+ })
+ .join('\n');
+}
+
+function normalize(value) {
+ return String(value).replace(/\r\n?/g, '\n');
+}
+
+function relative(value) {
+ return path.relative(repositoryRoot, value).split(path.sep).join('/');
+}
diff --git a/scripts/generate-startup-appearance-bootstrap.mjs b/scripts/generate-startup-appearance-bootstrap.mjs
index a9f89fb2f5..8d2c904bfd 100644
--- a/scripts/generate-startup-appearance-bootstrap.mjs
+++ b/scripts/generate-startup-appearance-bootstrap.mjs
@@ -1,6 +1,6 @@
import fs from 'node:fs';
import path from 'node:path';
-import { fileURLToPath } from 'node:url';
+import { fileURLToPath, pathToFileURL } from 'node:url';
import { createServer } from 'vite';
@@ -16,12 +16,42 @@ const appearancePromptSnapshotOutputPath = path.join(
repoRoot,
'src/crates/assembly/core/src/agentic/tools/implementations/generated/appearance_prompt_snapshots.json',
);
+const desktopBootstrapThemeOutputPath = path.join(
+ repoRoot,
+ 'src/apps/desktop/src/generated/bootstrap_theme.css',
+);
+const themePackageEntryPath = path.join(
+ repoRoot,
+ 'design-system/packages/theme-bitfun/dist/index.js',
+);
const checkOnly = process.argv.includes('--check');
function normalizeGeneratedText(content) {
return String(content).replace(/\r\n?/g, '\n');
}
+function createDesktopBootstrapThemeCss(themeValues, cssVariables) {
+ const declarations = Object.entries(themeValues)
+ .map(([name, value]) => {
+ const cssVariable = cssVariables[name];
+ if (!cssVariable) {
+ throw new Error(`Missing CSS variable mapping for bootstrap theme token ${name}.`);
+ }
+ return ` ${cssVariable}: ${String(value)};`;
+ })
+ .join('\n');
+
+ return [
+ '/* Generated by scripts/generate-startup-appearance-bootstrap.mjs. Do not edit. */',
+ '@layer bf.tokens.theme {',
+ ' :where([data-bf-design-system-root][data-color-scheme="dark"]) {',
+ declarations,
+ ' }',
+ '}',
+ '',
+ ].join('\n');
+}
+
const server = await createServer({
root: webUiRoot,
logLevel: 'error',
@@ -38,10 +68,12 @@ try {
{ builtinAppearancePalettes },
{ createStartupAppearanceBootstrapManifest },
{ createAppearancePromptSnapshotManifest },
+ { themes, themeCssVariables },
] = await Promise.all([
server.ssrLoadModule('/src/infrastructure/appearance/builtins/palettes.ts'),
server.ssrLoadModule('/src/infrastructure/appearance/builtins/startupAppearanceBootstrap.ts'),
server.ssrLoadModule('/src/infrastructure/appearance/builtins/appearancePromptSnapshots.ts'),
+ import(pathToFileURL(themePackageEntryPath).href),
]);
const generatedFiles = [
@@ -55,6 +87,11 @@ try {
outputPath: appearancePromptSnapshotOutputPath,
content: `${JSON.stringify(createAppearancePromptSnapshotManifest(builtinAppearancePalettes), null, 2)}\n`,
},
+ {
+ label: 'Desktop bootstrap theme projection',
+ outputPath: desktopBootstrapThemeOutputPath,
+ content: createDesktopBootstrapThemeCss(themes.dark, themeCssVariables),
+ },
];
for (const generatedFile of generatedFiles) {
diff --git a/scripts/mobile-ui-design-system.mjs b/scripts/mobile-ui-design-system.mjs
index 5b05fe974e..2f0504138c 100644
--- a/scripts/mobile-ui-design-system.mjs
+++ b/scripts/mobile-ui-design-system.mjs
@@ -102,6 +102,20 @@ function validateContract(tokenContract, componentContract, scenarioContract) {
for (const [name, value] of Object.entries(tokenContract.geometry ?? {})) {
if (!Number.isFinite(value) || value <= 0) throw new Error(`Invalid geometry token ${name}.`);
}
+ const availableTokenNames = new Set([
+ ...Object.keys(tokenContract.colors ?? {}),
+ ...Object.keys(tokenContract.typography ?? {}),
+ ...Object.keys(tokenContract.geometry ?? {}),
+ ...Object.keys(tokenContract.breakpoints ?? {}),
+ ...Object.keys(tokenContract.motion ?? {}),
+ ]);
+ for (const [componentName, component] of Object.entries(componentContract.components ?? {})) {
+ for (const tokenName of component.tokens ?? []) {
+ if (!availableTokenNames.has(tokenName)) {
+ throw new Error(`Component ${componentName} references unknown mobile token ${tokenName}.`);
+ }
+ }
+ }
const ids = new Set();
for (const scenario of scenarioContract.scenarios ?? []) {
if (!scenario.id || ids.has(scenario.id)) throw new Error(`Invalid or duplicate preview scenario id: ${scenario.id}.`);
@@ -118,13 +132,16 @@ function renderHarmonyColors(colors, appearance) {
}
function renderHarmonyTokens(contract) {
+ const colors = Object.entries(contract.colors)
+ .map(([name, pair]) => ` static readonly ${camel(name)}: MobileColorPair = new MobileColorPair(${quoted(pair.light)}, ${quoted(pair.dark)});`)
+ .join('\n');
const typography = Object.entries(contract.typography)
.map(([name, token]) => ` static readonly ${camel(name)}: MobileTypographyToken = new MobileTypographyToken(${token.size}, ${token.lineHeight}, ${token.weight});`)
.join('\n');
const geometry = renderNumberProperties(contract.geometry, ' static readonly');
const breakpoints = renderNumberProperties(contract.breakpoints, ' static readonly');
const motion = renderNumberProperties(contract.motion, ' static readonly');
- return `// Generated by scripts/mobile-ui-design-system.mjs. Do not edit.\n\nexport class MobileTypographyToken {\n readonly size: number;\n readonly lineHeight: number;\n readonly weight: number;\n\n constructor(size: number, lineHeight: number, weight: number) {\n this.size = size;\n this.lineHeight = lineHeight;\n this.weight = weight;\n }\n}\n\nexport class MobileDesignTypography {\n${typography}\n}\n\nexport class MobileDesignGeometry {\n${geometry}\n}\n\nexport class MobileDesignBreakpoints {\n${breakpoints}\n}\n\nexport class MobileDesignMotion {\n${motion}\n}\n`;
+ return `// Generated by scripts/mobile-ui-design-system.mjs. Do not edit.\n\nexport class MobileColorPair {\n readonly light: string;\n readonly dark: string;\n\n constructor(light: string, dark: string) {\n this.light = light;\n this.dark = dark;\n }\n}\n\nexport class MobileDesignColors {\n${colors}\n}\n\nexport class MobileTypographyToken {\n readonly size: number;\n readonly lineHeight: number;\n readonly weight: number;\n\n constructor(size: number, lineHeight: number, weight: number) {\n this.size = size;\n this.lineHeight = lineHeight;\n this.weight = weight;\n }\n}\n\nexport class MobileDesignTypography {\n${typography}\n}\n\nexport class MobileDesignGeometry {\n${geometry}\n}\n\nexport class MobileDesignBreakpoints {\n${breakpoints}\n}\n\nexport class MobileDesignMotion {\n${motion}\n}\n`;
}
function renderHarmonyScenarios(contract) {
diff --git a/scripts/mobile-ui-preview.mjs b/scripts/mobile-ui-preview.mjs
index feb89ce259..78e8a0a3c0 100644
--- a/scripts/mobile-ui-preview.mjs
+++ b/scripts/mobile-ui-preview.mjs
@@ -2,13 +2,17 @@
import { createReadStream, existsSync, readFileSync } from 'node:fs';
import { createServer } from 'node:http';
-import { extname, join, normalize, resolve } from 'node:path';
+import { extname, join, normalize, resolve, sep } from 'node:path';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
import { spawn } from 'node:child_process';
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
const PREVIEW_ROOT = join(ROOT, 'src', 'apps', 'mobile', 'design-system', 'preview');
+const SHARED_ASSETS = new Map([
+ ['/design-system-tokens.css', join(ROOT, 'design-system', 'packages', 'design-tokens', 'dist', 'tokens.css')],
+ ['/design-system-theme.css', join(ROOT, 'design-system', 'packages', 'theme-bitfun', 'dist', 'themes.css')],
+]);
const requiredFiles = ['index.html', 'preview.css', 'preview.js', 'generated/mobile-design-data.js'];
for (const file of requiredFiles) {
@@ -18,6 +22,12 @@ for (const file of requiredFiles) {
process.exit(1);
}
}
+for (const [requestPath, assetPath] of SHARED_ASSETS) {
+ if (!existsSync(assetPath) || readFileSync(assetPath, 'utf8').trim().length === 0) {
+ console.error(`[mobile-ui-preview] Missing canonical design-system asset for ${requestPath}.`);
+ process.exit(1);
+ }
+}
if (process.argv.includes('--check')) {
console.log('[mobile-ui-preview] Preview assets are present.');
@@ -30,9 +40,16 @@ const host = '127.0.0.1';
const url = `http://${host}:${port}`;
const server = createServer((request, response) => {
const requestPath = decodeURIComponent((request.url ?? '/').split('?')[0]);
+ const sharedAsset = SHARED_ASSETS.get(requestPath);
+ if (sharedAsset) {
+ response.setHeader('X-BitFun-Mobile-Preview', '1');
+ response.setHeader('Content-Type', contentType(extname(sharedAsset)));
+ createReadStream(sharedAsset).pipe(response);
+ return;
+ }
const relativePath = requestPath === '/' ? 'index.html' : requestPath.replace(/^\/+/, '');
const path = normalize(join(PREVIEW_ROOT, relativePath));
- if (!path.startsWith(`${PREVIEW_ROOT}/`) && path !== join(PREVIEW_ROOT, 'index.html')) {
+ if (!path.startsWith(`${PREVIEW_ROOT}${sep}`) && path !== join(PREVIEW_ROOT, 'index.html')) {
response.writeHead(403).end('Forbidden');
return;
}
diff --git a/scripts/theme-color-governance-baseline.design-lab.json b/scripts/theme-color-governance-baseline.design-lab.json
new file mode 100644
index 0000000000..9e639c6202
--- /dev/null
+++ b/scripts/theme-color-governance-baseline.design-lab.json
@@ -0,0 +1,47 @@
+{
+ "version": 1,
+ "description": "Design Lab canonical color governance baseline. Ordinary UI colors, compatibility aliases, fallbacks, and unresolved variables stay at zero.",
+ "budgets": {
+ "fallbackOccurrences": { "max": 0 },
+ "fallbackUniqueTokens": { "max": 0 },
+ "fallbackContracts.uncontractedUnique": { "max": 0 },
+ "fallbackContracts.staleRegisteredUnique": { "max": 0 },
+ "compatibilityAliases.usedUnique": { "max": 0 },
+ "compatibilityAliases.occurrences": { "max": 0 },
+ "compatibilityAliases.familyUsedUnique": { "max": 0 },
+ "compatibilityAliases.familyOccurrences": { "max": 0 },
+ "compatibilityAliases.missingCanonicalUnique": { "max": 0 },
+ "surfaceTokenRenames.activeUnique": { "max": 0 },
+ "surfaceTokenRenames.activeOccurrences": { "max": 0 },
+ "surfaceTokenRenames.missingCanonicalUnique": { "max": 0 },
+ "colorDomainContracts.missingRegisteredUnique": { "max": 0 },
+ "colorDomainContracts.staleRegisteredUnique": { "max": 0 },
+ "colorDomainContracts.activeUncontractedUnique": { "max": 0 },
+ "colorScopes.appUi.occurrences": { "max": 0 },
+ "colorScopes.appUi.uniqueColors": { "max": 0 },
+ "cssVarDefinitions.unresolvedUnique": { "max": 0 },
+ "cssVarDefinitions.unresolvedRequiredUnique": { "max": 0 },
+ "cssVarDefinitions.fallbackOnlyUnique": { "max": 0 },
+ "cssVarDefinitions.runtimeOnlyRequiredContractUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCrossFileUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractDynamicInputUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCssPrivateUnique": { "max": 0 },
+ "cssVarDefinitions.unregisteredDynamicFamilyUnique": { "max": 0 },
+ "cssVarDefinitions.dynamicFamilyUnexportedUnique": { "max": 0 },
+ "cssVarDefinitions.staleRegisteredDynamicFamilyUnique": { "max": 0 },
+ "tokenAliasLiterals.occurrences": { "max": 0 },
+ "tokenAliasLiterals.uniqueColors": { "max": 0 },
+ "nearPairs.indistinguishableTotal": { "max": 0 },
+ "nearPairs.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.appUi.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.appUi.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.assetMetadata.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.assetMetadata.nearTotal": { "max": 0 },
+ "colorDomainScopes.appUi.occurrences": { "max": 0 },
+ "colorDomainScopes.appUi.uniqueColors": { "max": 0 },
+ "colorDomainScopes.assetMetadata.occurrences": { "max": 0 },
+ "colorDomainScopes.assetMetadata.uniqueColors": { "max": 0 }
+ }
+}
diff --git a/scripts/theme-color-governance-baseline.design-system-ui.json b/scripts/theme-color-governance-baseline.design-system-ui.json
new file mode 100644
index 0000000000..ac9e57bffe
--- /dev/null
+++ b/scripts/theme-color-governance-baseline.design-system-ui.json
@@ -0,0 +1,22 @@
+{
+ "version": 1,
+ "description": "Public @bitfun/ui color governance baseline. Component CSS and mask assets consume only canonical peer-owned variables and remain free of literals and fallbacks.",
+ "budgets": {
+ "fallbackOccurrences": { "max": 0 },
+ "fallbackUniqueTokens": { "max": 0 },
+ "colorScopes.appUi.occurrences": { "max": 0 },
+ "colorScopes.appUi.uniqueColors": { "max": 0 },
+ "colorDomainScopes.assetMetadata.occurrences": { "max": 0 },
+ "colorDomainScopes.assetMetadata.uniqueColors": { "max": 0 },
+ "cssVarDefinitions.unresolvedUnique": { "max": 0 },
+ "cssVarDefinitions.unresolvedRequiredUnique": { "max": 0 },
+ "cssVarDefinitions.fallbackOnlyUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCrossFileUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractDynamicInputUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCssPrivateUnique": { "max": 0 },
+ "tokenAliasLiterals.occurrences": { "max": 0 },
+ "tokenAliasLiterals.uniqueColors": { "max": 0 },
+ "nearPairs.indistinguishableTotal": { "max": 0 },
+ "nearPairs.nearTotal": { "max": 0 }
+ }
+}
diff --git a/scripts/theme-color-governance-baseline.installer.json b/scripts/theme-color-governance-baseline.installer.json
index a8bf9f8c5e..b69327963d 100644
--- a/scripts/theme-color-governance-baseline.installer.json
+++ b/scripts/theme-color-governance-baseline.installer.json
@@ -1,117 +1,53 @@
{
"version": 1,
- "description": "Baseline for installer theme color governance. Lower values when debt is removed; do not raise without a documented review reason.",
+ "description": "Installer canonical color governance baseline. Ordinary UI consumes canonical variables while explicit installable theme presets remain the only palette owner.",
"budgets": {
- "fallbackOccurrences": {
- "max": 0
- },
- "fallbackUniqueTokens": {
- "max": 0
- },
- "fallbackContracts.uncontractedUnique": {
- "max": 0
- },
- "compatibilityAliases.usedUnique": {
- "max": 0
- },
- "compatibilityAliases.occurrences": {
- "max": 0
- },
- "compatibilityAliases.familyUsedUnique": {
- "max": 0
- },
- "compatibilityAliases.familyOccurrences": {
- "max": 0
- },
- "compatibilityAliases.missingCanonicalUnique": {
- "max": 0
- },
- "surfaceTokenRenames.activeUnique": {
- "max": 0
- },
- "surfaceTokenRenames.activeOccurrences": {
- "max": 0
- },
- "surfaceTokenRenames.missingCanonicalUnique": {
- "max": 0
- },
- "colorDomainContracts.missingRegisteredUnique": {
- "max": 0
- },
- "colorDomainContracts.staleRegisteredUnique": {
- "max": 0
- },
- "colorDomainContracts.activeUncontractedUnique": {
- "max": 0
- },
- "colorScopes.appUi.occurrences": {
- "max": 0
- },
- "colorScopes.appUi.uniqueColors": {
- "max": 0
- },
- "cssVarDefinitions.unresolvedRequiredUnique": {
- "max": 0
- },
- "cssVarDefinitions.fallbackOnlyUnique": {
- "max": 0
- },
- "cssVarDefinitions.nonContractCrossFileUnique": {
- "max": 0
- },
- "cssVarDefinitions.nonContractDynamicInputUnique": {
- "max": 0
- },
- "cssVarDefinitions.nonContractCssPrivateUnique": {
- "max": 0
- },
- "cssVarDefinitions.unregisteredDynamicFamilyUnique": {
- "max": 0
- },
- "tokenAliasLiterals.occurrences": {
- "max": 0
- },
- "nearPairs.indistinguishableTotal": {
- "max": 0
- },
- "nearPairs.nearTotal": {
- "max": 0
- },
- "colorDomainNearPairs.themePreset.indistinguishableTotal": {
- "max": 0
- },
- "colorDomainNearPairs.themePreset.nearTotal": {
- "max": 3
- },
- "colorDomainNearPairs.tokenContract.indistinguishableTotal": {
- "max": 0
- },
- "colorDomainNearPairs.tokenContract.nearTotal": {
- "max": 0
- },
- "colorDomainNearPairs.appUi.indistinguishableTotal": {
- "max": 0
- },
- "colorDomainNearPairs.appUi.nearTotal": {
- "max": 0
- },
- "colorDomainScopes.themePreset.occurrences": {
- "max": 47
- },
- "colorDomainScopes.themePreset.uniqueColors": {
- "max": 46
- },
- "colorDomainScopes.tokenContract.occurrences": {
- "max": 14
- },
- "colorDomainScopes.tokenContract.uniqueColors": {
- "max": 12
- },
- "colorDomainScopes.appUi.occurrences": {
- "max": 0
- },
- "colorDomainScopes.appUi.uniqueColors": {
- "max": 0
- }
+ "fallbackOccurrences": { "max": 0 },
+ "fallbackUniqueTokens": { "max": 0 },
+ "fallbackContracts.uncontractedUnique": { "max": 0 },
+ "fallbackContracts.staleRegisteredUnique": { "max": 0 },
+ "compatibilityAliases.usedUnique": { "max": 0 },
+ "compatibilityAliases.occurrences": { "max": 0 },
+ "compatibilityAliases.familyUsedUnique": { "max": 0 },
+ "compatibilityAliases.familyOccurrences": { "max": 0 },
+ "compatibilityAliases.missingCanonicalUnique": { "max": 0 },
+ "surfaceTokenRenames.activeUnique": { "max": 0 },
+ "surfaceTokenRenames.activeOccurrences": { "max": 0 },
+ "surfaceTokenRenames.missingCanonicalUnique": { "max": 0 },
+ "colorDomainContracts.missingRegisteredUnique": { "max": 0 },
+ "colorDomainContracts.staleRegisteredUnique": { "max": 0 },
+ "colorDomainContracts.activeUncontractedUnique": { "max": 0 },
+ "colorScopes.appUi.occurrences": { "max": 0 },
+ "colorScopes.appUi.uniqueColors": { "max": 0 },
+ "cssVarDefinitions.unresolvedUnique": { "max": 0 },
+ "cssVarDefinitions.unresolvedRequiredUnique": { "max": 0 },
+ "cssVarDefinitions.fallbackOnlyUnique": { "max": 0 },
+ "cssVarDefinitions.runtimeOnlyRequiredContractUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCrossFileUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractDynamicInputUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCssPrivateUnique": { "max": 0 },
+ "cssVarDefinitions.unregisteredDynamicFamilyUnique": { "max": 0 },
+ "cssVarDefinitions.dynamicFamilyUnexportedUnique": { "max": 0 },
+ "cssVarDefinitions.staleRegisteredDynamicFamilyUnique": { "max": 0 },
+ "tokenAliasLiterals.occurrences": { "max": 0 },
+ "tokenAliasLiterals.uniqueColors": { "max": 0 },
+ "nearPairs.indistinguishableTotal": { "max": 0 },
+ "nearPairs.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.appUi.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.appUi.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.assetMetadata.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.assetMetadata.nearTotal": { "max": 0 },
+ "colorDomainScopes.appUi.occurrences": { "max": 0 },
+ "colorDomainScopes.appUi.uniqueColors": { "max": 0 },
+ "colorDomainNearPairs.themePreset.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.themePreset.nearTotal": { "max": 0 },
+ "colorDomainScopes.themePreset.occurrences": { "max": 29 },
+ "colorDomainScopes.themePreset.uniqueColors": { "max": 29 },
+ "colorDomainScopes.tokenContract.occurrences": { "max": 0 },
+ "colorDomainScopes.tokenContract.uniqueColors": { "max": 0 },
+ "colorDomainScopes.assetMetadata.occurrences": { "max": 0 },
+ "colorDomainScopes.assetMetadata.uniqueColors": { "max": 0 }
}
}
diff --git a/scripts/theme-color-governance-baseline.json b/scripts/theme-color-governance-baseline.json
index 42b56789b2..767fb27fac 100644
--- a/scripts/theme-color-governance-baseline.json
+++ b/scripts/theme-color-governance-baseline.json
@@ -42,7 +42,7 @@
"max": 0
},
"surfaceTokenRenames.registeredUnique": {
- "max": 2
+ "max": 0
},
"surfaceTokenRenames.activeUnique": {
"max": 0
@@ -53,11 +53,11 @@
"surfaceTokenRenames.missingCanonicalUnique": {
"max": 0
},
- "generatedWidgetPayload.varUnique": {
- "max": 54
+ "generatedWidgetPayload.missingCanonicalThemeUnique": {
+ "max": 0
},
- "generatedWidgetPayload.occurrences": {
- "max": 54
+ "generatedWidgetPayload.nonCanonicalUnique": {
+ "max": 0
},
"generatedWidgetPayload.undefinedUnique": {
"max": 0
@@ -87,7 +87,7 @@
"max": 0
},
"colorDomainContracts.registeredUnique": {
- "max": 14
+ "max": 15
},
"colorDomainContracts.missingRegisteredUnique": {
"max": 0
@@ -105,10 +105,10 @@
"max": 0
},
"colorScopes.token.occurrences": {
- "max": 13
+ "max": 0
},
"colorScopes.token.uniqueColors": {
- "max": 10
+ "max": 0
},
"colorScopes.exception.uniqueColors": {
"max": 0
@@ -171,7 +171,7 @@
"max": 0
},
"colorDomainNearPairs.nearTotal": {
- "max": 6
+ "max": 5
},
"colorDomainNearPairs.themePreset.indistinguishableTotal": {
"max": 0
@@ -251,6 +251,12 @@
"colorDomainNearPairs.appUi.nearTotal": {
"max": 0
},
+ "colorDomainNearPairs.assetMetadata.indistinguishableTotal": {
+ "max": 0
+ },
+ "colorDomainNearPairs.assetMetadata.nearTotal": {
+ "max": 0
+ },
"colorDomainScopes.themePreset.occurrences": {
"max": 130
},
@@ -261,10 +267,10 @@
"max": 0
},
"colorDomainScopes.tokenContract.occurrences": {
- "max": 13
+ "max": 0
},
"colorDomainScopes.tokenContract.uniqueColors": {
- "max": 10
+ "max": 0
},
"colorDomainScopes.generatedWidget.occurrences": {
"max": 0
@@ -305,6 +311,9 @@
"colorDomainScopes.appUi.uniqueColors": {
"max": 0
},
+ "colorDomainScopes.assetMetadata.uniqueColors": {
+ "max": 7
+ },
"colorDomainScopes.mermaid.occurrences": {
"max": 0
},
@@ -315,7 +324,7 @@
"max": 0
},
"colorDomainNearPairs.appearanceProjection.nearTotal": {
- "max": 3
+ "max": 2
},
"colorDomainNearPairs.appearanceDomain.indistinguishableTotal": {
"max": 0
@@ -324,10 +333,10 @@
"max": 0
},
"colorDomainScopes.appearanceProjection.occurrences": {
- "max": 124
+ "max": 93
},
"colorDomainScopes.appearanceProjection.uniqueColors": {
- "max": 81
+ "max": 61
},
"colorDomainScopes.appearanceDomain.occurrences": {
"max": 0
diff --git a/scripts/theme-color-governance-baseline.miniapp-market.json b/scripts/theme-color-governance-baseline.miniapp-market.json
new file mode 100644
index 0000000000..f106c7012d
--- /dev/null
+++ b/scripts/theme-color-governance-baseline.miniapp-market.json
@@ -0,0 +1,47 @@
+{
+ "version": 1,
+ "description": "Mini App Market canonical color governance baseline. Ordinary UI colors, compatibility aliases, fallbacks, and unresolved variables stay at zero.",
+ "budgets": {
+ "fallbackOccurrences": { "max": 0 },
+ "fallbackUniqueTokens": { "max": 0 },
+ "fallbackContracts.uncontractedUnique": { "max": 0 },
+ "fallbackContracts.staleRegisteredUnique": { "max": 0 },
+ "compatibilityAliases.usedUnique": { "max": 0 },
+ "compatibilityAliases.occurrences": { "max": 0 },
+ "compatibilityAliases.familyUsedUnique": { "max": 0 },
+ "compatibilityAliases.familyOccurrences": { "max": 0 },
+ "compatibilityAliases.missingCanonicalUnique": { "max": 0 },
+ "surfaceTokenRenames.activeUnique": { "max": 0 },
+ "surfaceTokenRenames.activeOccurrences": { "max": 0 },
+ "surfaceTokenRenames.missingCanonicalUnique": { "max": 0 },
+ "colorDomainContracts.missingRegisteredUnique": { "max": 0 },
+ "colorDomainContracts.staleRegisteredUnique": { "max": 0 },
+ "colorDomainContracts.activeUncontractedUnique": { "max": 0 },
+ "colorScopes.appUi.occurrences": { "max": 0 },
+ "colorScopes.appUi.uniqueColors": { "max": 0 },
+ "cssVarDefinitions.unresolvedUnique": { "max": 0 },
+ "cssVarDefinitions.unresolvedRequiredUnique": { "max": 0 },
+ "cssVarDefinitions.fallbackOnlyUnique": { "max": 0 },
+ "cssVarDefinitions.runtimeOnlyRequiredContractUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCrossFileUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractDynamicInputUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCssPrivateUnique": { "max": 0 },
+ "cssVarDefinitions.unregisteredDynamicFamilyUnique": { "max": 0 },
+ "cssVarDefinitions.dynamicFamilyUnexportedUnique": { "max": 0 },
+ "cssVarDefinitions.staleRegisteredDynamicFamilyUnique": { "max": 0 },
+ "tokenAliasLiterals.occurrences": { "max": 0 },
+ "tokenAliasLiterals.uniqueColors": { "max": 0 },
+ "nearPairs.indistinguishableTotal": { "max": 0 },
+ "nearPairs.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.appUi.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.appUi.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.assetMetadata.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.assetMetadata.nearTotal": { "max": 0 },
+ "colorDomainScopes.appUi.occurrences": { "max": 0 },
+ "colorDomainScopes.appUi.uniqueColors": { "max": 0 },
+ "colorDomainScopes.assetMetadata.occurrences": { "max": 7 },
+ "colorDomainScopes.assetMetadata.uniqueColors": { "max": 5 }
+ }
+}
diff --git a/scripts/theme-color-governance-baseline.mobile-web.json b/scripts/theme-color-governance-baseline.mobile-web.json
index 7ae6e45364..091a07aada 100644
--- a/scripts/theme-color-governance-baseline.mobile-web.json
+++ b/scripts/theme-color-governance-baseline.mobile-web.json
@@ -1,105 +1,51 @@
{
"version": 1,
- "description": "Baseline for Mobile Web theme color governance. Lower values when debt is removed; do not raise without a documented review reason.",
+ "description": "Mobile Web canonical color governance baseline. The former local light/dark palettes and numbered accent ramps are retired.",
"budgets": {
- "fallbackOccurrences": {
- "max": 0
- },
- "fallbackUniqueTokens": {
- "max": 0
- },
- "fallbackContracts.uncontractedUnique": {
- "max": 0
- },
- "compatibilityAliases.usedUnique": {
- "max": 0
- },
- "compatibilityAliases.occurrences": {
- "max": 0
- },
- "compatibilityAliases.familyUsedUnique": {
- "max": 0
- },
- "compatibilityAliases.familyOccurrences": {
- "max": 0
- },
- "compatibilityAliases.missingCanonicalUnique": {
- "max": 0
- },
- "surfaceTokenRenames.activeUnique": {
- "max": 0
- },
- "surfaceTokenRenames.activeOccurrences": {
- "max": 0
- },
- "surfaceTokenRenames.missingCanonicalUnique": {
- "max": 0
- },
- "colorDomainContracts.missingRegisteredUnique": {
- "max": 0
- },
- "colorDomainContracts.staleRegisteredUnique": {
- "max": 0
- },
- "colorDomainContracts.activeUncontractedUnique": {
- "max": 0
- },
- "colorScopes.appUi.occurrences": {
- "max": 0
- },
- "colorScopes.appUi.uniqueColors": {
- "max": 0
- },
- "cssVarDefinitions.unresolvedRequiredUnique": {
- "max": 0
- },
- "cssVarDefinitions.fallbackOnlyUnique": {
- "max": 0
- },
- "cssVarDefinitions.nonContractCrossFileUnique": {
- "max": 0
- },
- "cssVarDefinitions.nonContractDynamicInputUnique": {
- "max": 0
- },
- "cssVarDefinitions.nonContractCssPrivateUnique": {
- "max": 0
- },
- "cssVarDefinitions.unregisteredDynamicFamilyUnique": {
- "max": 0
- },
- "tokenAliasLiterals.occurrences": {
- "max": 0
- },
- "nearPairs.indistinguishableTotal": {
- "max": 0
- },
- "nearPairs.nearTotal": {
- "max": 0
- },
- "colorDomainNearPairs.themePreset.indistinguishableTotal": {
- "max": 0
- },
- "colorDomainNearPairs.themePreset.nearTotal": {
- "max": 0
- },
- "colorDomainNearPairs.appUi.indistinguishableTotal": {
- "max": 0
- },
- "colorDomainNearPairs.appUi.nearTotal": {
- "max": 0
- },
- "colorDomainScopes.themePreset.occurrences": {
- "max": 33
- },
- "colorDomainScopes.themePreset.uniqueColors": {
- "max": 29
- },
- "colorDomainScopes.appUi.occurrences": {
- "max": 0
- },
- "colorDomainScopes.appUi.uniqueColors": {
- "max": 0
- }
+ "fallbackOccurrences": { "max": 0 },
+ "fallbackUniqueTokens": { "max": 0 },
+ "fallbackContracts.uncontractedUnique": { "max": 0 },
+ "fallbackContracts.staleRegisteredUnique": { "max": 0 },
+ "compatibilityAliases.usedUnique": { "max": 0 },
+ "compatibilityAliases.occurrences": { "max": 0 },
+ "compatibilityAliases.familyUsedUnique": { "max": 0 },
+ "compatibilityAliases.familyOccurrences": { "max": 0 },
+ "compatibilityAliases.missingCanonicalUnique": { "max": 0 },
+ "surfaceTokenRenames.activeUnique": { "max": 0 },
+ "surfaceTokenRenames.activeOccurrences": { "max": 0 },
+ "surfaceTokenRenames.missingCanonicalUnique": { "max": 0 },
+ "colorDomainContracts.missingRegisteredUnique": { "max": 0 },
+ "colorDomainContracts.staleRegisteredUnique": { "max": 0 },
+ "colorDomainContracts.activeUncontractedUnique": { "max": 0 },
+ "colorScopes.appUi.occurrences": { "max": 0 },
+ "colorScopes.appUi.uniqueColors": { "max": 0 },
+ "cssVarDefinitions.unresolvedUnique": { "max": 0 },
+ "cssVarDefinitions.unresolvedRequiredUnique": { "max": 0 },
+ "cssVarDefinitions.fallbackOnlyUnique": { "max": 0 },
+ "cssVarDefinitions.runtimeOnlyRequiredContractUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCrossFileUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractDynamicInputUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCssPrivateUnique": { "max": 0 },
+ "cssVarDefinitions.unregisteredDynamicFamilyUnique": { "max": 0 },
+ "cssVarDefinitions.dynamicFamilyUnexportedUnique": { "max": 0 },
+ "cssVarDefinitions.staleRegisteredDynamicFamilyUnique": { "max": 0 },
+ "tokenAliasLiterals.occurrences": { "max": 0 },
+ "tokenAliasLiterals.uniqueColors": { "max": 0 },
+ "nearPairs.indistinguishableTotal": { "max": 0 },
+ "nearPairs.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.appUi.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.appUi.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.assetMetadata.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.assetMetadata.nearTotal": { "max": 0 },
+ "colorDomainScopes.appUi.occurrences": { "max": 0 },
+ "colorDomainScopes.appUi.uniqueColors": { "max": 0 },
+ "colorDomainNearPairs.themePreset.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.themePreset.nearTotal": { "max": 0 },
+ "colorDomainScopes.themePreset.occurrences": { "max": 0 },
+ "colorDomainScopes.themePreset.uniqueColors": { "max": 0 },
+ "colorDomainScopes.assetMetadata.occurrences": { "max": 4 },
+ "colorDomainScopes.assetMetadata.uniqueColors": { "max": 1 }
}
}
diff --git a/scripts/theme-color-governance-baseline.skin-market.json b/scripts/theme-color-governance-baseline.skin-market.json
new file mode 100644
index 0000000000..78f5e52d25
--- /dev/null
+++ b/scripts/theme-color-governance-baseline.skin-market.json
@@ -0,0 +1,47 @@
+{
+ "version": 1,
+ "description": "Skin Market canonical color governance baseline. Ordinary UI colors, compatibility aliases, fallbacks, and unresolved variables stay at zero.",
+ "budgets": {
+ "fallbackOccurrences": { "max": 0 },
+ "fallbackUniqueTokens": { "max": 0 },
+ "fallbackContracts.uncontractedUnique": { "max": 0 },
+ "fallbackContracts.staleRegisteredUnique": { "max": 0 },
+ "compatibilityAliases.usedUnique": { "max": 0 },
+ "compatibilityAliases.occurrences": { "max": 0 },
+ "compatibilityAliases.familyUsedUnique": { "max": 0 },
+ "compatibilityAliases.familyOccurrences": { "max": 0 },
+ "compatibilityAliases.missingCanonicalUnique": { "max": 0 },
+ "surfaceTokenRenames.activeUnique": { "max": 0 },
+ "surfaceTokenRenames.activeOccurrences": { "max": 0 },
+ "surfaceTokenRenames.missingCanonicalUnique": { "max": 0 },
+ "colorDomainContracts.missingRegisteredUnique": { "max": 0 },
+ "colorDomainContracts.staleRegisteredUnique": { "max": 0 },
+ "colorDomainContracts.activeUncontractedUnique": { "max": 0 },
+ "colorScopes.appUi.occurrences": { "max": 0 },
+ "colorScopes.appUi.uniqueColors": { "max": 0 },
+ "cssVarDefinitions.unresolvedUnique": { "max": 0 },
+ "cssVarDefinitions.unresolvedRequiredUnique": { "max": 0 },
+ "cssVarDefinitions.fallbackOnlyUnique": { "max": 0 },
+ "cssVarDefinitions.runtimeOnlyRequiredContractUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCrossFileUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractDynamicInputUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCssPrivateUnique": { "max": 0 },
+ "cssVarDefinitions.unregisteredDynamicFamilyUnique": { "max": 0 },
+ "cssVarDefinitions.dynamicFamilyUnexportedUnique": { "max": 0 },
+ "cssVarDefinitions.staleRegisteredDynamicFamilyUnique": { "max": 0 },
+ "tokenAliasLiterals.occurrences": { "max": 0 },
+ "tokenAliasLiterals.uniqueColors": { "max": 0 },
+ "nearPairs.indistinguishableTotal": { "max": 0 },
+ "nearPairs.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.appUi.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.appUi.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.assetMetadata.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.assetMetadata.nearTotal": { "max": 0 },
+ "colorDomainScopes.appUi.occurrences": { "max": 0 },
+ "colorDomainScopes.appUi.uniqueColors": { "max": 0 },
+ "colorDomainScopes.assetMetadata.occurrences": { "max": 6 },
+ "colorDomainScopes.assetMetadata.uniqueColors": { "max": 5 }
+ }
+}
diff --git a/scripts/theme-color-governance-baseline.website.json b/scripts/theme-color-governance-baseline.website.json
new file mode 100644
index 0000000000..e43a81e383
--- /dev/null
+++ b/scripts/theme-color-governance-baseline.website.json
@@ -0,0 +1,47 @@
+{
+ "version": 1,
+ "description": "Website canonical color governance baseline. Ordinary UI colors, compatibility aliases, fallbacks, and unresolved variables stay at zero.",
+ "budgets": {
+ "fallbackOccurrences": { "max": 0 },
+ "fallbackUniqueTokens": { "max": 0 },
+ "fallbackContracts.uncontractedUnique": { "max": 0 },
+ "fallbackContracts.staleRegisteredUnique": { "max": 0 },
+ "compatibilityAliases.usedUnique": { "max": 0 },
+ "compatibilityAliases.occurrences": { "max": 0 },
+ "compatibilityAliases.familyUsedUnique": { "max": 0 },
+ "compatibilityAliases.familyOccurrences": { "max": 0 },
+ "compatibilityAliases.missingCanonicalUnique": { "max": 0 },
+ "surfaceTokenRenames.activeUnique": { "max": 0 },
+ "surfaceTokenRenames.activeOccurrences": { "max": 0 },
+ "surfaceTokenRenames.missingCanonicalUnique": { "max": 0 },
+ "colorDomainContracts.missingRegisteredUnique": { "max": 0 },
+ "colorDomainContracts.staleRegisteredUnique": { "max": 0 },
+ "colorDomainContracts.activeUncontractedUnique": { "max": 0 },
+ "colorScopes.appUi.occurrences": { "max": 0 },
+ "colorScopes.appUi.uniqueColors": { "max": 0 },
+ "cssVarDefinitions.unresolvedUnique": { "max": 0 },
+ "cssVarDefinitions.unresolvedRequiredUnique": { "max": 0 },
+ "cssVarDefinitions.fallbackOnlyUnique": { "max": 0 },
+ "cssVarDefinitions.runtimeOnlyRequiredContractUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCrossFileUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractDynamicInputUnique": { "max": 0 },
+ "cssVarDefinitions.nonContractCssPrivateUnique": { "max": 0 },
+ "cssVarDefinitions.unregisteredDynamicFamilyUnique": { "max": 0 },
+ "cssVarDefinitions.dynamicFamilyUnexportedUnique": { "max": 0 },
+ "cssVarDefinitions.staleRegisteredDynamicFamilyUnique": { "max": 0 },
+ "tokenAliasLiterals.occurrences": { "max": 0 },
+ "tokenAliasLiterals.uniqueColors": { "max": 0 },
+ "nearPairs.indistinguishableTotal": { "max": 0 },
+ "nearPairs.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.appUi.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.appUi.nearTotal": { "max": 0 },
+ "colorDomainNearPairs.assetMetadata.indistinguishableTotal": { "max": 0 },
+ "colorDomainNearPairs.assetMetadata.nearTotal": { "max": 0 },
+ "colorDomainScopes.appUi.occurrences": { "max": 0 },
+ "colorDomainScopes.appUi.uniqueColors": { "max": 0 },
+ "colorDomainScopes.assetMetadata.occurrences": { "max": 0 },
+ "colorDomainScopes.assetMetadata.uniqueColors": { "max": 0 }
+ }
+}
diff --git a/scripts/theme-color-near-pair-decisions.json b/scripts/theme-color-near-pair-decisions.json
index 73c7876fd9..3549ad2e75 100644
--- a/scripts/theme-color-near-pair-decisions.json
+++ b/scripts/theme-color-near-pair-decisions.json
@@ -3,7 +3,7 @@
"description": "Explicit decisions for specialized theme near-color pairs. Keep this file in sync with scripts/audit-theme-colors.mjs output; lower the audit baseline when a pair is merged.",
"decisions": [
{
- "root": "src/web-ui/src",
+ "root": "src/web-ui",
"domain": "themePreset",
"key": "#1a1b26 <-> #1c1c1f",
"decision": "keep",
@@ -12,7 +12,7 @@
"reevaluateWhen": "Only after a visual review proves Tokyo Night no longer needs a distinct primary background identity."
},
{
- "root": "src/web-ui/src",
+ "root": "src/web-ui",
"domain": "themePreset",
"key": "#1c1c1f <-> #212019",
"decision": "keep",
@@ -21,7 +21,7 @@
"reevaluateWhen": "Only if China Night gets a separate editor lineHighlight token or visual review proves the current-line cue remains visible."
},
{
- "root": "src/web-ui/src",
+ "root": "src/web-ui",
"domain": "themePreset",
"key": "#2b2d30 <-> #313335",
"decision": "keep",
@@ -30,7 +30,7 @@
"reevaluateWhen": "Only after a Midnight surface-ramp redesign removes the adjacent role split."
},
{
- "root": "src/web-ui/src",
+ "root": "src/web-ui",
"domain": "appearanceProjection",
"key": "#0451a5 <-> #0550ae",
"decision": "keep",
@@ -39,49 +39,13 @@
"reevaluateWhen": "Reevaluate only when terminal ANSI and workbench link roles share a reviewed palette contract."
},
{
- "root": "src/web-ui/src",
- "domain": "appearanceProjection",
- "key": "rgba(0, 0, 0, 0.12) <-> rgba(0, 0, 0, 0.15)",
- "decision": "keep",
- "owner": "src/web-ui/src/infrastructure/appearance/builtins/buildBuiltinAppearance.ts",
- "reason": "The black overlay ladder separates subtle and stronger elevation states in light Appearance packages; both stops are intentional adjacent-state values.",
- "reevaluateWhen": "Reevaluate when the light Appearance overlay ladder is redesigned with focused surface-state screenshots."
- },
- {
- "root": "src/web-ui/src",
+ "root": "src/web-ui",
"domain": "appearanceProjection",
"key": "rgba(255, 255, 255, 0.12) <-> rgba(255, 255, 255, 0.15)",
"decision": "keep",
"owner": "src/web-ui/src/infrastructure/appearance/builtins/buildBuiltinAppearance.ts",
"reason": "The white overlay ladder separates subtle and stronger elevation states in dark Appearance packages; both stops are intentional adjacent-state values.",
"reevaluateWhen": "Reevaluate when the dark Appearance overlay ladder is redesigned with focused surface-state screenshots."
- },
- {
- "root": "BitFun-Installer/src",
- "domain": "themePreset",
- "key": "#0e0e10 <-> #121214",
- "decision": "keep",
- "owner": "BitFun-Installer/src/theme/installerThemesData.ts",
- "reason": "ThemeSetup renders dark theme cards side by side with primary and secondary preview backgrounds. Cyber needs its own darker primary preview seed so the named theme is not distinguishable only by label and accent.",
- "reevaluateWhen": "Only if installer theme selection adds a separate identity swatch or screenshots prove the primary preview no longer carries theme identity."
- },
- {
- "root": "BitFun-Installer/src",
- "domain": "themePreset",
- "key": "#1a1b26 <-> #1a1c1e",
- "decision": "keep",
- "owner": "BitFun-Installer/src/theme/installerThemesData.ts",
- "reason": "Tokyo Night appears as an adjacent installer preview card, and its primary background should preserve the Tokyo base hue while the shared installer card surface stays neutral.",
- "reevaluateWhen": "Only after installer preview cards are redesigned to use a dedicated non-background theme identity affordance."
- },
- {
- "root": "BitFun-Installer/src",
- "domain": "themePreset",
- "key": "#121214 <-> #1a1814",
- "decision": "keep",
- "owner": "BitFun-Installer/src/theme/installerThemesData.ts",
- "reason": "Ink Night uses a warmer dark primary background in adjacent installer preview cards. Collapsing it into the canonical dark seed makes multiple dark choices visually flatter before the app is installed.",
- "reevaluateWhen": "Only if visual review shows installer dark theme cards no longer rely on primary background identity."
}
]
}
diff --git a/scripts/theme-css-var-contract.mjs b/scripts/theme-css-var-contract.mjs
index 08b384a592..5a470d092f 100644
--- a/scripts/theme-css-var-contract.mjs
+++ b/scripts/theme-css-var-contract.mjs
@@ -41,16 +41,41 @@ export const PACKAGE_CSS_VAR_DEFINITION_CONTRACTS = Object.freeze([
}),
]);
-export const DEFAULT_ROOT = 'src/web-ui/src';
+export const PACKAGE_CSS_VAR_IMPORT_CONTRACTS = Object.freeze([
+ Object.freeze({
+ specifier: '@bitfun/design-tokens/tokens.css',
+ packageNames: Object.freeze(['@bitfun/design-tokens']),
+ }),
+ Object.freeze({
+ specifier: '@bitfun/theme-bitfun/default.css',
+ packageNames: Object.freeze(['@bitfun/design-tokens', '@bitfun/theme-bitfun']),
+ }),
+ Object.freeze({
+ specifier: '@bitfun/theme-bitfun/themes.css',
+ packageNames: Object.freeze(['@bitfun/theme-bitfun']),
+ }),
+]);
+
+export const DEFAULT_ROOT = 'src/web-ui';
export const DEFAULT_BASELINE_PATH = 'scripts/theme-color-governance-baseline.json';
-export const COLOR_EXTENSIONS = new Set(['.css', '.scss', '.sass', '.ts', '.tsx', '.js', '.jsx']);
+export const COLOR_EXTENSIONS = new Set([
+ '.css',
+ '.html',
+ '.js',
+ '.jsx',
+ '.mjs',
+ '.sass',
+ '.scss',
+ '.svg',
+ '.ts',
+ '.tsx',
+ '.webmanifest',
+]);
export const TOKEN_PATH_PARTS = [
- 'BitFun-Installer/src/styles/variables.css',
'BitFun-Installer/src/theme',
'component-library/styles',
- 'theme/presets',
];
export const TOKEN_ALIAS_SOURCE_PATH_PARTS = [
@@ -58,18 +83,17 @@ export const TOKEN_ALIAS_SOURCE_PATH_PARTS = [
];
export const CONTRACT_VAR_DEFINITION_PATH_PARTS = [
- 'BitFun-Installer/src/styles/variables.css',
'BitFun-Installer/src/theme/installerThemeRuntime.ts',
'component-library/styles',
'infrastructure/appearance',
- 'src/mobile-web/src/theme/presets',
+ 'src/mobile-web/src/styles/global.scss',
'tools/bitfun-canvas/runtime/styles',
'tools/generative-widget/appearancePayload.ts',
];
export const STATIC_CONTRACT_VAR_DEFINITION_PATH_PARTS = [
- 'BitFun-Installer/src/styles/variables.css',
'component-library/styles',
+ 'src/mobile-web/src/styles/global.scss',
];
export const RUNTIME_CONTRACT_VAR_DEFINITION_PATH_PARTS = [
@@ -86,6 +110,12 @@ export const EXCEPTION_PATH_PARTS = [
];
export const COLOR_DOMAIN_RULES = [
+ {
+ key: 'assetMetadata',
+ label: 'Static asset and install metadata',
+ pathParts: ['assets', 'public/favicon', 'site.webmanifest', 'src/assets'],
+ extensions: ['.svg', '.webmanifest'],
+ },
{
key: 'appearanceProjection',
label: 'Appearance projections',
@@ -104,7 +134,7 @@ export const COLOR_DOMAIN_RULES = [
{
key: 'tokenContract',
label: 'Token contracts',
- pathParts: ['BitFun-Installer/src/styles/variables.css', 'component-library/styles'],
+ pathParts: ['component-library/styles'],
},
{
key: 'generatedWidget',
@@ -175,6 +205,12 @@ export const COLOR_DOMAIN_LABELS = Object.fromEntries([
]);
export const COLOR_DOMAIN_CONTRACTS = [
+ {
+ key: 'assetMetadata',
+ owner: 'src/web-ui/src/app/components/NavPanel/assets; src/web-ui/public/assets; src/mobile-web/src/assets; src/miniapp-market-web/public; src/skin-market-web/public',
+ reason: 'Favicons, install metadata, and self-contained vector assets cannot consume runtime CSS variables and therefore own their serialized colors at the asset boundary.',
+ mergePolicy: 'Keep only identity or platform metadata colors here; any rendered application UI color must move to a canonical theme token.',
+ },
{
key: 'appearanceProjection',
owner: 'src/web-ui/src/infrastructure/appearance/builtins/buildBuiltinAppearance.ts',
@@ -183,15 +219,15 @@ export const COLOR_DOMAIN_CONTRACTS = [
},
{
key: 'themePreset',
- owner: 'src/web-ui/src/infrastructure/appearance/builtins',
+ owner: 'src/web-ui/src/infrastructure/appearance/builtins; BitFun-Installer/src/theme',
reason: 'Builtin appearances own primitive palette mapping and must keep per-appearance personality instead of being folded into shared app tokens.',
mergePolicy: 'Only merge exact duplicate primitive values after confirming the theme still exposes distinct semantic roles.',
},
{
key: 'themeRuntime',
- owner: 'src/web-ui/src/infrastructure/appearance/adapters/CssTokenAppearanceAdapter.ts',
- reason: 'AppearanceRuntime applies the registered CSS token projection for static CSS, web preview, and embedded surface payloads.',
- mergePolicy: 'Keep the runtime projection canonical and reject reintroduction of compatibility aliases or surface-local token owners.',
+ owner: 'src/web-ui/src/infrastructure/appearance/adapters/ThemeTokenAppearanceAdapter.ts',
+ reason: 'AppearanceRuntime applies the registered canonical theme, product-domain, and component token payloads.',
+ mergePolicy: 'Keep runtime payloads canonical and reject compatibility aliases or surface-local token owners.',
},
{
key: 'tokenContract',
@@ -267,20 +303,7 @@ export const TOKEN_COMPATIBILITY_ALIAS_FAMILY_CONTRACTS = [];
export const FALLBACK_VAR_CONTRACTS = [];
-export const SURFACE_TOKEN_RENAME_CONTRACTS = [
- {
- key: '--m-editor-highlight-rgb',
- canonical: '--private-markdown-editor-highlight-rgb',
- owner: 'src/web-ui/src/tools/editor/meditor/components/TiptapEditor.scss',
- reason: 'Markdown editor highlight color should use the component-private markdown-editor helper instead of the abbreviated meditor local key.',
- },
- {
- key: '--m-editor-highlight-border-rgb',
- canonical: '--private-markdown-editor-highlight-border-rgb',
- owner: 'src/web-ui/src/tools/editor/meditor/components/TiptapEditor.scss',
- reason: 'Markdown editor highlight border color should use the component-private markdown-editor helper instead of the abbreviated meditor local key.',
- },
-];
+export const SURFACE_TOKEN_RENAME_CONTRACTS = [];
export const DYNAMIC_VAR_FAMILY_CONTRACTS = [
{
@@ -293,26 +316,16 @@ export const DYNAMIC_VAR_FAMILY_CONTRACTS = [
owner: 'src/web-ui/src/tools/bitfun-canvas/runtime/canvasRuntimeInstaller.ts; src/web-ui/src/tools/bitfun-canvas/runtime/styles/canvas-runtime.scss',
reason: 'BitFun Canvas iframe runtime receives host Appearance values through a scoped CSS variable family that must stay isolated from app root tokens.',
},
- {
- prefix: '--color-accent-',
- owner: 'src/mobile-web/src/theme/presets',
- reason: 'Mobile presets export the active accent palette scale by numeric stop.',
- },
- {
- prefix: '--color-purple-',
- owner: 'src/mobile-web/src/theme/presets',
- reason: 'Mobile presets export the secondary accent palette by numeric stop.',
- },
- {
- prefix: '--color-pink-',
- owner: 'src/mobile-web/src/theme/presets',
- reason: 'Mobile presets export assistant-mode identity accents by numeric stop for session and picker states.',
- },
{
prefix: '--bf-font-size-',
owner: 'src/web-ui/src/infrastructure/font-preference/core/FontPreferenceService.ts',
reason: 'Font preference runtime overrides the canonical design-system font-size primitives so every semantic role follows one global scale.',
},
+ {
+ prefix: '--mobile-',
+ owner: 'src/apps/mobile/design-system/preview/preview.js; src/apps/mobile/design-system/preview/preview.css',
+ reason: 'The native comparison preview projects the validated mobile token contract into a scoped device canvas without exposing those values as canonical web theme tokens.',
+ },
];
export const REGISTERED_DYNAMIC_VAR_PREFIXES = new Set(
diff --git a/scripts/theme-visual-governance-contract.json b/scripts/theme-visual-governance-contract.json
index 4f51d97b1a..97ea309a9e 100644
--- a/scripts/theme-visual-governance-contract.json
+++ b/scripts/theme-visual-governance-contract.json
@@ -9,7 +9,7 @@
"formFactors": ["desktop", "narrow"],
"themes": ["dark", "light", "system", "bitfun-monochrome"],
"states": ["default", "hover", "focus", "selected", "disabled"],
- "tokenFamilies": ["--bf-appearance-token-color-bg-*", "--bf-appearance-token-color-text-*", "--bf-appearance-token-chrome-*", "--bf-appearance-token-element-bg-*", "--bf-appearance-token-border-*", "--bitfun-nav-*"],
+ "tokenFamilies": ["--bf-color-surface-*", "--bf-color-content-*", "--bf-color-border-*", "--bf-color-action-*", "--bf-component-scene-*", "--bitfun-nav-*"],
"evidence": [
{
"type": "theme-color-audit",
@@ -22,7 +22,7 @@
}
],
"risks": [
- "Web UI visual values must remain owned by the active Appearance projection.",
+ "Web UI visual values must resolve through canonical design-system tokens projected by the active Appearance.",
"System theme resolution must not assume desktop-only media query behavior."
]
},
@@ -33,7 +33,7 @@
"formFactors": ["desktop", "narrow"],
"themes": ["dark", "light", "system", "bitfun-monochrome"],
"states": ["default", "streaming", "hover", "focus", "selected", "error", "empty"],
- "tokenFamilies": ["--bf-appearance-token-flowchat-*", "--bf-appearance-token-tool-card-*", "--bf-appearance-token-color-bg-scene", "--bf-appearance-token-color-text-*", "--bf-appearance-token-color-accent-*"],
+ "tokenFamilies": ["--bf-color-surface-*", "--bf-color-content-*", "--bf-color-accent-*", "--bf-color-action-*", "--bf-color-status-*", "--bf-domain-tool-*"],
"evidence": [
{
"type": "theme-color-audit",
@@ -47,7 +47,7 @@
],
"risks": [
"Streaming and virtualized items can hide token regressions until historical turns are rendered.",
- "Flow Chat has many visual states; every shared token family must remain in the Appearance contract."
+ "Flow Chat has many visual states; shared colors must stay in the canonical theme contract and tool identity colors in the registered domain contract."
]
},
{
@@ -57,7 +57,7 @@
"formFactors": ["desktop", "narrow"],
"themes": ["dark", "light", "system"],
"states": ["default", "expanded", "collapsed", "hover", "focus", "success", "warning", "error"],
- "tokenFamilies": ["--bf-appearance-token-tool-card-*", "--bf-appearance-token-color-success*", "--bf-appearance-token-color-warning*", "--bf-appearance-token-color-error*"],
+ "tokenFamilies": ["--bf-color-surface-*", "--bf-color-border-*", "--bf-color-status-*", "--bf-color-action-*", "--bf-domain-tool-*"],
"evidence": [
{
"type": "theme-color-audit",
@@ -81,7 +81,7 @@
"formFactors": ["desktop", "narrow"],
"themes": ["dark", "light", "system"],
"states": ["default", "focus", "selection", "search", "added", "deleted", "changed", "conflict"],
- "tokenFamilies": ["Monaco palette", "--diff-editor-*", "--bf-appearance-token-git-color-*", "--bf-appearance-token-color-text-*"],
+ "tokenFamilies": ["Monaco palette", "--bf-domain-git-*", "--bf-color-content-*", "--bf-color-surface-*", "--bf-color-status-*"],
"evidence": [
{
"type": "theme-color-audit",
@@ -105,7 +105,7 @@
"formFactors": ["desktop", "narrow"],
"themes": ["dark", "light", "system"],
"states": ["default", "focus", "selection", "ansi-normal", "ansi-bright", "error"],
- "tokenFamilies": ["terminal ANSI palette", "--bf-appearance-token-color-text-*", "--bf-appearance-token-border-*"],
+ "tokenFamilies": ["terminal ANSI palette", "--bf-color-content-*", "--bf-color-surface-*", "--bf-color-border-*", "--bf-color-status-*"],
"evidence": [
{
"type": "theme-color-audit",
@@ -129,7 +129,7 @@
"formFactors": ["desktop", "narrow"],
"themes": ["dark", "light", "system"],
"states": ["default", "code", "table", "link", "diagram", "error"],
- "tokenFamilies": ["--markdown-*", "--markdown-primary-color", "Mermaid palette", "Prism palette"],
+ "tokenFamilies": ["--bf-color-content-*", "--bf-color-surface-*", "--bf-domain-mermaid-*", "--bf-domain-prism-*", "Mermaid renderer palette"],
"evidence": [
{
"type": "theme-color-audit",
@@ -142,7 +142,7 @@
}
],
"risks": [
- "--markdown-primary-color is the embedded-content accent override and must remain distinct from generic app primary aliases.",
+ "Embedded Markdown uses canonical content and surface roles while Mermaid and Prism retain registered renderer-domain roles.",
"Mermaid graph roles do not map directly to app status colors."
]
},
@@ -153,7 +153,7 @@
"formFactors": ["iframe", "desktop", "narrow"],
"themes": ["dark", "light", "system"],
"states": ["fallback-before-host-payload", "host-payload", "loading", "error"],
- "tokenFamilies": ["--bf-appearance-token-color-*", "--bf-appearance-token-border-*", "--bf-appearance-token-element-bg-*", "--bf-appearance-token-size-radius-*", "--bf-appearance-token-size-gap-*"],
+ "tokenFamilies": ["--bf-color-*", "--bf-shadow-*", "--bf-effect-*", "--bf-opacity-*", "--bf-radius-*", "--bf-space-*"],
"evidence": [
{
"type": "boundary-render-review",
@@ -162,7 +162,7 @@
{
"type": "theme-color-audit",
"command": "pnpm run theme:color-audit",
- "requirement": "Generated widget fallback colors must be derived from a builtin Appearance package."
+ "requirement": "Generated widget values must come from the canonical theme package contract and the selected builtin Appearance projection."
}
],
"risks": [
@@ -177,7 +177,7 @@
"formFactors": ["desktop", "narrow"],
"themes": ["dark", "light", "system", "bitfun-monochrome"],
"states": ["default", "selected", "hover", "focus", "imported-appearance", "system-appearance"],
- "tokenFamilies": ["--bf-appearance-token-color-accent-*", "--bf-appearance-token-color-bg-*", "--bf-appearance-token-color-text-*", "--bf-appearance-token-border-*", "--bf-appearance-token-element-bg-*", "--bf-appearance-token-config-page-*"],
+ "tokenFamilies": ["--bf-color-*", "--bf-shadow-*", "--bf-effect-*", "--bf-opacity-*", "--bf-component-config-page-*", "--bf-domain-*"],
"evidence": [
{
"type": "theme-color-audit",
@@ -191,17 +191,17 @@
],
"risks": [
"Theme selection can resolve differently under system mode.",
- "Custom theme previews can expose missing runtime aliases before ordinary components do."
+ "Imported v2 theme-token packages must validate against the canonical root and scoped token registries before preview or activation."
]
},
{
"key": "mobile-web-shell",
- "owner": "src/mobile-web; src/web-ui/src/component-library/styles",
+ "owner": "src/mobile-web/src/theme; src/mobile-web/src/styles",
"platforms": ["mobile-web"],
"formFactors": ["mobile", "narrow"],
"themes": ["dark", "light", "system"],
"states": ["default", "loading", "error", "navigation"],
- "tokenFamilies": ["shared web tokens", "--bf-appearance-token-color-bg-*", "--bf-appearance-token-color-text-*", "--bf-appearance-token-border-*"],
+ "tokenFamilies": ["@bitfun/theme-bitfun", "--bf-color-surface-*", "--bf-color-content-*", "--bf-color-border-*", "--bf-color-action-*", "--bf-color-status-*"],
"evidence": [
{
"type": "mobile-build-review",
@@ -221,7 +221,7 @@
"formFactors": ["desktop", "narrow"],
"themes": ["dark", "light", "system", "bitfun-dark", "bitfun-light", "bitfun-midnight", "bitfun-china-style", "bitfun-china-night", "bitfun-cyber", "bitfun-slate", "bitfun-tokyo-night"],
"states": ["theme-setup", "language", "options", "loading", "progress", "error", "completed", "hover", "focus"],
- "tokenFamilies": ["--bf-appearance-token-color-bg-*", "--bf-appearance-token-color-text-*", "--bf-appearance-token-element-bg-*", "--bf-appearance-token-border-*", "--bf-appearance-token-color-accent-*", "--bf-appearance-token-color-success", "--bf-appearance-token-color-warning", "--bf-appearance-token-color-error"],
+ "tokenFamilies": ["@bitfun/theme-bitfun", "--bf-color-surface-*", "--bf-color-content-*", "--bf-color-border-*", "--bf-color-action-*", "--bf-color-accent-*", "--bf-color-status-*"],
"evidence": [
{
"type": "theme-color-audit",
diff --git a/src/apps/desktop/bootstrap-ui/frontend-update-confirm.html b/src/apps/desktop/bootstrap-ui/frontend-update-confirm.html
index 224cc131b1..14bc2a22b4 100644
--- a/src/apps/desktop/bootstrap-ui/frontend-update-confirm.html
+++ b/src/apps/desktop/bootstrap-ui/frontend-update-confirm.html
@@ -1,25 +1,26 @@
-
+
Review frontend update
+
diff --git a/src/apps/desktop/bootstrap-ui/index.html b/src/apps/desktop/bootstrap-ui/index.html
index 362dffc6d1..da483c8335 100644
--- a/src/apps/desktop/bootstrap-ui/index.html
+++ b/src/apps/desktop/bootstrap-ui/index.html
@@ -1,15 +1,16 @@
-
+
BitFun recovery
+
diff --git a/src/apps/desktop/src/appearance.rs b/src/apps/desktop/src/appearance.rs
index 21cf5aaf47..7adf374fab 100644
--- a/src/apps/desktop/src/appearance.rs
+++ b/src/apps/desktop/src/appearance.rs
@@ -392,14 +392,20 @@ impl AppearanceConfig {
root.setAttribute('data-bf-appearance', '{id}');
root.setAttribute('data-bf-appearance-mode', '{appearance_mode}');
+ root.setAttribute('data-bf-design-system-root', '');
+ root.setAttribute('data-color-scheme', '{appearance_mode}');
+ root.setAttribute('data-contrast', 'standard');
+ root.setAttribute('data-density', 'compact');
- root.style.setProperty('--bf-appearance-token-color-bg-primary', '{bg_primary}');
- root.style.setProperty('--bf-appearance-token-color-bg-secondary', '{bg_secondary}');
- root.style.setProperty('--bf-appearance-token-color-bg-tertiary', '{bg_primary}');
- root.style.setProperty('--bf-appearance-token-color-bg-workbench', '{bg_primary}');
- root.style.setProperty('--bf-appearance-token-color-bg-scene', '{bg_scene}');
- root.style.setProperty('--bf-appearance-token-color-text-primary', '{text_primary}');
- root.style.setProperty('--bf-appearance-token-color-accent-500', '{accent_color}');
+ root.style.setProperty('--bf-color-surface-canvas', '{bg_primary}');
+ root.style.setProperty('--bf-color-surface-panel', '{bg_secondary}');
+ root.style.setProperty('--bf-color-surface-tertiary', '{bg_primary}');
+ root.style.setProperty('--bf-color-surface-workbench', '{bg_primary}');
+ root.style.setProperty('--bf-color-surface-scene', '{bg_scene}');
+ root.style.setProperty('--bf-color-surface-chrome', '{bg_primary}');
+ root.style.setProperty('--bf-color-content-primary', '{text_primary}');
+ root.style.setProperty('--bf-color-content-muted', '{text_muted}');
+ root.style.setProperty('--bf-color-accent-default', '{accent_color}');
root.style.backgroundColor = '{bg_primary}';
if (document.body) {{
@@ -428,6 +434,7 @@ impl AppearanceConfig {
bg_secondary = self.bg_secondary,
bg_scene = self.bg_scene,
text_primary = self.text_primary,
+ text_muted = self.text_muted,
accent_color = self.accent_color,
startup_trace_id_json = startup_trace_id_json,
perf_trace_enabled = perf_trace_enabled,
@@ -479,10 +486,14 @@ mod startup_appearance_tests {
assert!(script.contains("__BITFUN_BOOTSTRAP_APPEARANCE_SELECTION__"));
assert!(script.contains("data-bf-appearance"));
assert!(script.contains("data-bf-appearance-mode"));
- assert!(script.contains("--bf-appearance-token-color-bg-primary"));
- assert!(script.contains("--bf-appearance-token-color-bg-scene"));
- assert!(script.contains("--bf-appearance-token-color-text-primary"));
- assert!(script.contains("--bf-appearance-token-color-accent-500"));
+ assert!(script.contains("data-bf-design-system-root"));
+ assert!(script.contains("data-color-scheme"));
+ assert!(script.contains("--bf-color-surface-canvas"));
+ assert!(script.contains("--bf-color-surface-scene"));
+ assert!(script.contains("--bf-color-content-primary"));
+ assert!(script.contains("--bf-color-content-muted"));
+ assert!(script.contains("--bf-color-accent-default"));
+ assert!(!script.contains("--bf-appearance-token-"));
let retired_bootstrap_global = ["__BITFUN_BOOTSTRAP", "THEME"].join("_");
let retired_background_token = ["--", "color-bg-"].concat();
let retired_text_token = ["--", "color-text-"].concat();
diff --git a/src/apps/desktop/src/frontend_workbench.rs b/src/apps/desktop/src/frontend_workbench.rs
index 98a937dfa8..190a9b79c0 100644
--- a/src/apps/desktop/src/frontend_workbench.rs
+++ b/src/apps/desktop/src/frontend_workbench.rs
@@ -24,6 +24,7 @@ const TRANSACTION_WAIT_GRACE: Duration = Duration::from_secs(3);
const STATE_SCHEMA_VERSION: u32 = 2;
const RECOVERY_HTML: &[u8] = include_bytes!("../bootstrap-ui/index.html");
const CONFIRMATION_HTML: &[u8] = include_bytes!("../bootstrap-ui/frontend-update-confirm.html");
+const BOOTSTRAP_THEME_CSS: &[u8] = include_bytes!("generated/bootstrap_theme.css");
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default, rename_all = "camelCase")]
@@ -755,6 +756,17 @@ impl FrontendWorkbenchManager {
request: tauri::http::Request>,
) -> tauri::http::Response> {
let request_path = request.uri().path();
+ if request_path == "/bootstrap-theme.css" {
+ return tauri::http::Response::builder()
+ .status(tauri::http::StatusCode::OK)
+ .header(
+ tauri::http::header::CONTENT_TYPE,
+ "text/css; charset=utf-8",
+ )
+ .header(tauri::http::header::CACHE_CONTROL, "no-store, max-age=0")
+ .body(BOOTSTRAP_THEME_CSS.to_vec())
+ .unwrap_or_else(|_| tauri::http::Response::new(Vec::new()));
+ }
if request_path == "/frontend-update-confirm.html" {
return tauri::http::Response::builder()
.status(tauri::http::StatusCode::OK)
@@ -1769,4 +1781,26 @@ mod tests {
assert!(body.contains("confirm_frontend_update"));
assert!(body.contains("rollback_frontend_update"));
}
+
+ #[test]
+ fn protocol_serves_the_generated_bootstrap_theme_without_an_active_revision() {
+ let temp = tempfile::tempdir().expect("tempdir");
+ let manager = FrontendWorkbenchManager::new(temp.path());
+ let request = tauri::http::Request::builder()
+ .uri("bitfun-ui://localhost/bootstrap-theme.css")
+ .body(Vec::new())
+ .expect("request");
+
+ let response = manager.protocol_response(request);
+ let body = String::from_utf8_lossy(response.body());
+
+ assert_eq!(response.status(), tauri::http::StatusCode::OK);
+ assert_eq!(
+ response.headers().get(tauri::http::header::CONTENT_TYPE),
+ Some(&tauri::http::HeaderValue::from_static("text/css; charset=utf-8"))
+ );
+ assert!(body.contains("--bf-color-surface-canvas"));
+ assert!(body.contains("--bf-color-status-danger-content"));
+ assert!(!body.contains("--bf-appearance-token-"));
+ }
}
diff --git a/src/apps/desktop/src/generated/bootstrap_theme.css b/src/apps/desktop/src/generated/bootstrap_theme.css
new file mode 100644
index 0000000000..f8787d804d
--- /dev/null
+++ b/src/apps/desktop/src/generated/bootstrap_theme.css
@@ -0,0 +1,105 @@
+/* Generated by scripts/generate-startup-appearance-bootstrap.mjs. Do not edit. */
+@layer bf.tokens.theme {
+ :where([data-bf-design-system-root][data-color-scheme="dark"]) {
+ --bf-color-accent-border: color-mix(in srgb, #60a5fa 40%, transparent);
+ --bf-color-accent-border-subtle: color-mix(in srgb, #60a5fa 25%, transparent);
+ --bf-color-accent-default: #60a5fa;
+ --bf-color-accent-disabled: rgba(96, 165, 250, 0.30);
+ --bf-color-accent-hover: #3b82f6;
+ --bf-color-accent-secondary: #8b5cf6;
+ --bf-color-accent-secondary-border: color-mix(in srgb, #8b5cf6 25%, transparent);
+ --bf-color-accent-secondary-hover: #7c6b99;
+ --bf-color-accent-secondary-surface: color-mix(in srgb, #8b5cf6 9%, transparent);
+ --bf-color-accent-secondary-surface-strong: color-mix(in srgb, #8b5cf6 15%, transparent);
+ --bf-color-accent-surface: color-mix(in srgb, #60a5fa 9%, transparent);
+ --bf-color-accent-surface-strong: color-mix(in srgb, #60a5fa 15%, transparent);
+ --bf-color-accent-surface-subtle: color-mix(in srgb, #60a5fa 5%, transparent);
+ --bf-color-action-neutral-border: rgba(255, 255, 255, 0.18);
+ --bf-color-action-neutral-content: #b0b0b0;
+ --bf-color-action-neutral-content-disabled: #555555;
+ --bf-color-action-neutral-fill-border: rgba(255, 255, 255, 0.1);
+ --bf-color-action-neutral-surface: rgba(255, 255, 255, 0.1);
+ --bf-color-action-neutral-surface-hover: rgba(255, 255, 255, 0.12);
+ --bf-color-action-neutral-surface-pressed: rgba(255, 255, 255, 0.15);
+ --bf-color-action-primary-background: rgba(255, 255, 255, 0.16);
+ --bf-color-action-primary-content: #f3f3f5;
+ --bf-color-action-primary-hover: rgba(255, 255, 255, 0.24);
+ --bf-color-action-primary-pressed: rgba(255, 255, 255, 0.2);
+ --bf-color-action-quiet-content: #b0b0b0;
+ --bf-color-action-quiet-hover: rgba(255, 255, 255, 0.06);
+ --bf-color-action-quiet-pressed: rgba(255, 255, 255, 0.1);
+ --bf-color-action-secondary-background: rgba(255, 255, 255, 0.06);
+ --bf-color-action-secondary-content: #e8e8e8;
+ --bf-color-action-secondary-hover: rgba(255, 255, 255, 0.1);
+ --bf-color-action-secondary-pressed: rgba(255, 255, 255, 0.12);
+ --bf-color-border-default: rgba(255, 255, 255, 0.18);
+ --bf-color-border-strong: rgba(255, 255, 255, 0.3);
+ --bf-color-border-subtle: rgba(255, 255, 255, 0.12);
+ --bf-color-content-disabled: #555555;
+ --bf-color-content-inverse: #0e0e10;
+ --bf-color-content-muted: #858585;
+ --bf-color-content-on-dark: #ffffff;
+ --bf-color-content-on-light: #000000;
+ --bf-color-content-primary: #e8e8e8;
+ --bf-color-content-secondary: #b0b0b0;
+ --bf-color-control-switch-thumb: #ffffff;
+ --bf-color-control-switch-track: #555555;
+ --bf-color-control-switch-track-checked: #34c78c;
+ --bf-color-field-background: #1c1c1f;
+ --bf-color-field-background-hover: rgba(255, 255, 255, 0.06);
+ --bf-color-field-border: rgba(255, 255, 255, 0.18);
+ --bf-color-field-border-focus: #60a5fa;
+ --bf-color-field-border-hover: rgba(255, 255, 255, 0.24);
+ --bf-color-focus-ring: #60a5fa;
+ --bf-color-identity-assistant-border: color-mix(in srgb, #ec4899 15%, transparent);
+ --bf-color-identity-assistant-content: #ec4899;
+ --bf-color-identity-assistant-content-hover: #f472b6;
+ --bf-color-identity-assistant-surface: color-mix(in srgb, #ec4899 9%, transparent);
+ --bf-color-identity-assistant-surface-subtle: color-mix(in srgb, #ec4899 5%, transparent);
+ --bf-color-key-hint-background: rgba(255, 255, 255, 0.1);
+ --bf-color-link-default: #60a5fa;
+ --bf-color-link-hover: #93c5fd;
+ --bf-color-overlay-scrim: rgba(0, 0, 0, 0.56);
+ --bf-color-scrollbar-thumb: rgba(255, 255, 255, 0.12);
+ --bf-color-scrollbar-thumb-hover: rgba(255, 255, 255, 0.15);
+ --bf-color-status-danger-border: rgba(239, 68, 68, 0.3);
+ --bf-color-status-danger-content: #ef4444;
+ --bf-color-status-danger-surface: rgba(239, 68, 68, 0.1);
+ --bf-color-status-info-border: rgba(255, 255, 255, 0.24);
+ --bf-color-status-info-content: #a1a1aa;
+ --bf-color-status-info-surface: rgba(255, 255, 255, 0.08);
+ --bf-color-status-success-border: rgba(52, 211, 153, 0.3);
+ --bf-color-status-success-content: #34d399;
+ --bf-color-status-success-surface: rgba(52, 211, 153, 0.1);
+ --bf-color-status-warning-border: rgba(245, 158, 11, 0.3);
+ --bf-color-status-warning-content: #f59e0b;
+ --bf-color-status-warning-surface: rgba(245, 158, 11, 0.1);
+ --bf-color-surface-canvas: #0e0e10;
+ --bf-color-surface-chrome: #0e0e10;
+ --bf-color-surface-panel: #1c1c1f;
+ --bf-color-surface-raised: #1c1c1f;
+ --bf-color-surface-scene: #1c1c1f;
+ --bf-color-surface-subtle: rgba(255, 255, 255, 0.06);
+ --bf-color-surface-tertiary: #0e0e10;
+ --bf-color-surface-workbench: #0e0e10;
+ --bf-effect-blur-base: blur(8px) saturate(1.1);
+ --bf-effect-blur-medium: blur(12px) saturate(1.2);
+ --bf-effect-blur-subtle: blur(4px) saturate(1.05);
+ --bf-opacity-disabled: 0.6;
+ --bf-opacity-focus: 0.9;
+ --bf-opacity-hover: 0.8;
+ --bf-opacity-muted: 0.8;
+ --bf-shadow-accent-glow: 0 12px 32px color-mix(in srgb, #3b82f6 25%, transparent), 0 6px 16px color-mix(in srgb, #60a5fa 18%, transparent), 0 3px 8px rgba(0, 0, 0, 0.12);
+ --bf-shadow-base: 0 4px 8px rgba(0, 0, 0, 0.7);
+ --bf-shadow-composer: 0 2px 6px rgba(0, 0, 0, 0.32);
+ --bf-shadow-inner-highlight: inset 0 1px 0 rgba(255, 255, 255, 0.08);
+ --bf-shadow-inner-highlight-hover: inset 0 1px 0 rgba(255, 255, 255, 0.24);
+ --bf-shadow-lg: 0 8px 16px rgba(0, 0, 0, 0.6);
+ --bf-shadow-menu: 0 4px 10px rgba(0, 0, 0, 0.48);
+ --bf-shadow-overlay: 0 4px 20px rgba(0, 0, 0, 0.48);
+ --bf-shadow-raised: 0 2px 4px rgba(0, 0, 0, 0.8);
+ --bf-shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.8);
+ --bf-shadow-xl: 0 12px 24px rgba(0, 0, 0, 0.5);
+ --bf-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.9);
+ }
+}
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/account/AccountScreen.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/account/AccountScreen.kt
index 6a6370e67d..d6bbbc5b8c 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/account/AccountScreen.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/account/AccountScreen.kt
@@ -37,7 +37,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
@@ -57,6 +56,7 @@ import com.bitfun.mobile.app.viewmodel.AccountViewModel
import com.bitfun.mobile.core.feature.account.AccountFailureReason
import com.bitfun.mobile.core.feature.account.AccountIntent
import com.bitfun.mobile.core.feature.account.AccountUiState
+import com.bitfun.mobile.app.ui.theme.bitFunColors
private val AccountCardShape = RoundedCornerShape(24.dp)
@@ -177,8 +177,8 @@ private fun AccountInput(
focusedContainerColor = MaterialTheme.colorScheme.surface,
unfocusedContainerColor = MaterialTheme.colorScheme.surface,
disabledContainerColor = MaterialTheme.colorScheme.surface,
- focusedIndicatorColor = Color.Transparent,
- unfocusedIndicatorColor = Color.Transparent,
+ focusedIndicatorColor = bitFunColors.transparent,
+ unfocusedIndicatorColor = bitFunColors.transparent,
cursorColor = MaterialTheme.colorScheme.onSurface,
focusedTextColor = MaterialTheme.colorScheme.onSurface,
unfocusedTextColor = MaterialTheme.colorScheme.onSurface,
@@ -222,7 +222,7 @@ private fun AccountProfilePage(
Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
Text(stringResource(R.string.account_bitfun_account), fontSize = 17.sp, fontWeight = FontWeight.Bold)
Spacer(Modifier.weight(1f))
- Text(stringResource(R.string.remote_settings_account_signed_in), fontSize = 14.sp, color = com.bitfun.mobile.app.ui.theme.bitFunColors.success)
+ Text(stringResource(R.string.remote_settings_account_signed_in), fontSize = 14.sp, color = com.bitfun.mobile.app.ui.theme.bitFunColors.statusSuccess)
}
Text(stringResource(R.string.account_signed_in_body, state.username), fontSize = 14.sp, lineHeight = 20.sp, color = MaterialTheme.colorScheme.onSurfaceVariant)
}
@@ -254,7 +254,7 @@ private fun AccountProfilePage(
},
),
fontSize = 13.sp,
- color = if (device.online) com.bitfun.mobile.app.ui.theme.bitFunColors.success else MaterialTheme.colorScheme.onSurfaceVariant,
+ color = if (device.online) com.bitfun.mobile.app.ui.theme.bitFunColors.statusSuccess else MaterialTheme.colorScheme.onSurfaceVariant,
)
}
if (reconnectable) Surface(color = MaterialTheme.colorScheme.surfaceVariant, shape = RoundedCornerShape(14.dp)) {
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/BitFunHeaderActionMenu.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/BitFunHeaderActionMenu.kt
index 8e88510d46..3edbd75fde 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/BitFunHeaderActionMenu.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/BitFunHeaderActionMenu.kt
@@ -49,6 +49,7 @@ import androidx.compose.ui.window.PopupProperties
import com.bitfun.mobile.app.ui.theme.BitFunEaseOut
import com.bitfun.mobile.app.ui.theme.MotionQuickMillis
import com.bitfun.mobile.app.ui.theme.generated.MobileDesignGeometry
+import com.bitfun.mobile.app.ui.theme.bitFunColors
internal const val HEADER_ACTION_MENU_TEST_TAG: String = "header-action-menu"
@@ -197,7 +198,7 @@ private fun HeaderActionRow(action: BitFunHeaderAction, onDismiss: () -> Unit) {
.clip(RoundedCornerShape(10.dp))
.background(
if (action.selected) MaterialTheme.colorScheme.surfaceVariant
- else androidx.compose.ui.graphics.Color.Transparent,
+ else bitFunColors.transparent,
)
.clickable(enabled = action.enabled) {
action.onClick()
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/ChatStatusBar.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/ChatStatusBar.kt
index 64d552e666..bb15002439 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/ChatStatusBar.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/ChatStatusBar.kt
@@ -55,7 +55,7 @@ internal fun ChatStatusBar(
val stopLabel = stringResource(R.string.message_stop)
val statusLabel = if (detail != title) "$title · $detail" else title
val statusColor = when (ConnectionStatusPresenter.tone(phase)) {
- ConnectionTone.OK -> bitFunColors.success
+ ConnectionTone.OK -> bitFunColors.statusSuccess
ConnectionTone.BUSY -> MaterialTheme.colorScheme.onSurfaceVariant
ConnectionTone.ERROR -> MaterialTheme.colorScheme.error
ConnectionTone.MUTED -> MaterialTheme.colorScheme.onSurfaceVariant
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/ComposerBar.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/ComposerBar.kt
index 26a8376279..8e879e039a 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/ComposerBar.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/ComposerBar.kt
@@ -50,7 +50,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.onFocusChanged
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
@@ -72,6 +71,7 @@ import com.bitfun.mobile.app.R
import com.bitfun.mobile.app.ui.theme.BitFunEaseOut
import com.bitfun.mobile.app.ui.theme.MotionQuickMillis
import com.bitfun.mobile.app.ui.theme.MotionStructureMillis
+import com.bitfun.mobile.app.ui.theme.bitFunColors
import com.bitfun.mobile.app.ui.theme.generated.MobileDesignBreakpoints
import com.bitfun.mobile.app.ui.theme.generated.MobileDesignGeometry
import com.bitfun.mobile.core.feature.connection.ConnectionPhase
@@ -602,7 +602,7 @@ private fun ModelSelectorContent(
)
.background(
if (option.selected) MaterialTheme.colorScheme.surfaceVariant
- else Color.Transparent,
+ else bitFunColors.transparent,
)
.clickable { onSelect(option.id) }
.semantics {
@@ -688,7 +688,7 @@ private fun PrimaryActionButton(
modifier = Modifier
.size(ActionSize)
.clip(CircleShape)
- .background(if (action == ComposerPrimaryAction.STOP) colors.error else Color.Transparent)
+ .background(if (action == ComposerPrimaryAction.STOP) colors.error else bitFunColors.transparent)
.clickable(enabled = enabled) {
when (action) {
ComposerPrimaryAction.STOP -> onStop()
@@ -775,9 +775,8 @@ private fun AttachmentStrip(
)
}
}
- // The badge carries its own scrim rather than borrowing the
- // theme's: it sits on whatever the photo happens to be, and a
- // pale photo would swallow a surface-coloured control.
+ // Media controls sit over arbitrary photo content, so their
+ // scrim is a dedicated mobile design token.
val removeLabel = stringResource(R.string.message_remove_image)
Box(
contentAlignment = Alignment.Center,
@@ -785,20 +784,17 @@ private fun AttachmentStrip(
.align(Alignment.TopEnd)
.size(32.dp)
.clip(CircleShape)
- .background(BadgeScrim)
+ .background(bitFunColors.mediaScrim)
.clickable(role = Role.Button, enabled = enabled) { onRemove(image.id) }
.semantics { contentDescription = removeLabel },
) {
Text(
"×",
style = MaterialTheme.typography.labelMedium,
- color = Color.White,
+ color = MaterialTheme.colorScheme.onPrimary,
)
}
}
}
}
}
-
-/** `#AA222222` from the other client — a scrim, so it is not a theme role. */
-private val BadgeScrim = Color(0xAA222222)
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/tool/ToolStatusList.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/tool/ToolStatusList.kt
index e28cb54b24..d13f2855f8 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/tool/ToolStatusList.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/chat/tool/ToolStatusList.kt
@@ -23,7 +23,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@@ -37,6 +36,7 @@ import com.bitfun.mobile.core.feature.session.ToolOperation
import com.bitfun.mobile.core.feature.session.ToolPhase
import com.bitfun.mobile.core.feature.session.ToolRow
import com.bitfun.mobile.core.feature.session.collapseToolRows
+import com.bitfun.mobile.app.ui.theme.bitFunColors
/** Anything the desktop must be told about a rejection needs a reason; this is ours. */
private const val REJECT_REASON = "Rejected from the Android client"
@@ -193,13 +193,13 @@ internal fun ToolStatusRow(
color = if (emphasized) {
MaterialTheme.colorScheme.surfaceVariant
} else {
- Color.Transparent
+ bitFunColors.transparent
},
shape = RoundedCornerShape(if (emphasized) 14.dp else 8.dp),
)
.border(
width = if (emphasized) 1.dp else 0.dp,
- color = if (emphasized) MaterialTheme.colorScheme.outlineVariant else Color.Transparent,
+ color = if (emphasized) MaterialTheme.colorScheme.outlineVariant else bitFunColors.transparent,
shape = RoundedCornerShape(if (emphasized) 14.dp else 8.dp),
)
.padding(
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/common/AdaptiveModalSurface.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/common/AdaptiveModalSurface.kt
index 9da8e461a9..f4a510430a 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/common/AdaptiveModalSurface.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/common/AdaptiveModalSurface.kt
@@ -58,7 +58,7 @@ internal fun AdaptiveModalSurface(
Box(
modifier = Modifier
.fillMaxSize()
- .background(bitFunColors.modalScrim)
+ .background(MaterialTheme.colorScheme.scrim)
.clickable(onClick = onDismissRequest)
.safeDrawingPadding()
.imePadding(),
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/remote/ConnectAccountDeviceScreen.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/remote/ConnectAccountDeviceScreen.kt
index b1793135a0..9d113a8849 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/remote/ConnectAccountDeviceScreen.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/remote/ConnectAccountDeviceScreen.kt
@@ -260,7 +260,7 @@ private fun DeviceListCard(
),
fontSize = 13.sp,
color = if (device.online) {
- bitFunColors.success
+ bitFunColors.statusSuccess
} else {
MaterialTheme.colorScheme.onSurfaceVariant
},
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/remote/ConnectView.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/remote/ConnectView.kt
index 9e74e45599..d4cd8122ea 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/remote/ConnectView.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/remote/ConnectView.kt
@@ -343,7 +343,7 @@ private fun ManualPairing(
val consumeTouches = remember { MutableInteractionSource() }
Box(
modifier = modifier
- .background(bitFunColors.modalScrim)
+ .background(MaterialTheme.colorScheme.scrim)
.clickable(enabled = !connecting, onClick = onBack),
contentAlignment = Alignment.Center,
) {
@@ -525,7 +525,7 @@ private fun CameraFrame() {
modifier = Modifier
.size(282.dp)
.clip(RoundedCornerShape(40.dp))
- .background(Color.Black.copy(alpha = 0.10f)),
+ .background(bitFunColors.shadowMedium),
) {
ScanCorner(accent, Alignment.TopStart, true, true)
ScanCorner(accent, Alignment.TopEnd, false, true)
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/remote/RemoteSessionListView.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/remote/RemoteSessionListView.kt
index a6c5e5cea2..e23c5b9e2e 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/remote/RemoteSessionListView.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/remote/RemoteSessionListView.kt
@@ -39,7 +39,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onGloballyPositioned
@@ -73,6 +72,7 @@ import com.bitfun.mobile.core.feature.session.SessionWorkspaceContext
import com.bitfun.mobile.core.feature.workspace.RemoteWorkspaceIntent
import com.bitfun.mobile.core.feature.workspace.RemoteWorkspaceUiState
import kotlinx.coroutines.delay
+import com.bitfun.mobile.app.ui.theme.bitFunColors
internal const val SESSION_LIST_TEST_TAG: String = "session-list"
internal const val SESSION_PROJECTS_TEST_TAG: String = "session-projects"
@@ -786,7 +786,7 @@ private fun SessionRow(
.heightIn(min = if (metadata.isEmpty()) 46.dp else 56.dp)
.clip(RoundedCornerShape(10.dp))
.background(
- if (selected) MaterialTheme.colorScheme.secondaryContainer else Color.Transparent,
+ if (selected) MaterialTheme.colorScheme.secondaryContainer else bitFunColors.transparent,
)
.onGloballyPositioned { coordinates ->
anchorBounds = coordinates.boundsInWindow().toIntRect()
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/settings/ModelServiceScreen.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/settings/ModelServiceScreen.kt
index 09d6034782..5d271d7bb8 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/settings/ModelServiceScreen.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/settings/ModelServiceScreen.kt
@@ -421,7 +421,7 @@ private fun AccountModelSelection(
.clip(RoundedCornerShape(9.dp))
.background(
if (model.id == activeModelId) MaterialTheme.colorScheme.surfaceVariant
- else Color.Transparent,
+ else bitFunColors.transparent,
)
.clickable { onSelect(model.id) }
.padding(horizontal = 10.dp),
@@ -791,7 +791,7 @@ private fun LocalModelEditor(
Text(
stringResource(R.string.model_service_test_success),
style = MaterialTheme.typography.bodySmall,
- color = bitFunColors.success,
+ color = bitFunColors.statusSuccess,
)
}
}
@@ -849,9 +849,9 @@ private fun SoftTextField(
focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant,
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant,
disabledContainerColor = MaterialTheme.colorScheme.surfaceVariant,
- focusedIndicatorColor = Color.Transparent,
- unfocusedIndicatorColor = Color.Transparent,
- disabledIndicatorColor = Color.Transparent,
+ focusedIndicatorColor = bitFunColors.transparent,
+ unfocusedIndicatorColor = bitFunColors.transparent,
+ disabledIndicatorColor = bitFunColors.transparent,
),
modifier = modifier.fillMaxWidth().defaultMinSize(minHeight = 48.dp),
)
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/AppSidebar.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/AppSidebar.kt
index 5c08b4cb75..da99575b77 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/AppSidebar.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/AppSidebar.kt
@@ -24,7 +24,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/SidebarChrome.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/SidebarChrome.kt
index 2d3c7899ce..ee541496f8 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/SidebarChrome.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/SidebarChrome.kt
@@ -66,7 +66,7 @@ internal fun ConnectionDot(phase: ConnectionPhase) {
// BUSY is the one addition, because a dot that only ever goes green or grey
// cannot say "connecting" while it is still trying.
val color: Color = when (tone) {
- ConnectionTone.OK -> bitFunColors.success
+ ConnectionTone.OK -> bitFunColors.statusSuccess
ConnectionTone.BUSY -> MaterialTheme.colorScheme.tertiary
ConnectionTone.ERROR -> MaterialTheme.colorScheme.error
ConnectionTone.MUTED -> MaterialTheme.colorScheme.onSurfaceVariant
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/SidebarRemoteWorkspaceSection.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/SidebarRemoteWorkspaceSection.kt
index ea65f2138d..ec15e7401d 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/SidebarRemoteWorkspaceSection.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/SidebarRemoteWorkspaceSection.kt
@@ -30,7 +30,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Rect
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.testTag
@@ -53,6 +52,7 @@ import com.bitfun.mobile.core.feature.shell.RemoteSidebarSessionRow
import com.bitfun.mobile.core.feature.shell.RemoteSidebarWorkspaceRow
import com.bitfun.mobile.core.feature.session.RemoteSessionUiState
import com.bitfun.mobile.core.feature.workspace.RemoteWorkspaceUiState
+import com.bitfun.mobile.app.ui.theme.bitFunColors
private const val SESSIONS_PER_WORKSPACE = 3
private const val WORKSPACES_PER_BATCH = 3
@@ -629,7 +629,7 @@ private fun RemoteSessionRow(
.fillMaxWidth()
.height(44.dp)
.clip(RoundedCornerShape(10.dp))
- .background(if (selected) MaterialTheme.colorScheme.surfaceVariant else Color.Transparent)
+ .background(if (selected) MaterialTheme.colorScheme.surfaceVariant else bitFunColors.transparent)
.onGloballyPositioned { coordinates ->
anchorBounds = coordinates.boundsInWindow().toIntRect()
}
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/SidebarSessionList.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/SidebarSessionList.kt
index 64d4af54e9..ccaca14a1d 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/SidebarSessionList.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/shell/sidebar/SidebarSessionList.kt
@@ -26,7 +26,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onGloballyPositioned
@@ -45,6 +44,7 @@ import androidx.compose.ui.unit.sp
import com.bitfun.mobile.app.R
import com.bitfun.mobile.core.feature.shell.SidebarSections
import com.bitfun.mobile.core.feature.shell.SidebarSessionRow
+import com.bitfun.mobile.app.ui.theme.bitFunColors
internal const val SIDEBAR_PINNED_TEST_TAG: String = "app-sidebar-pinned"
internal const val SIDEBAR_ARCHIVED_TEST_TAG: String = "app-sidebar-archived"
@@ -186,7 +186,7 @@ private fun SessionRow(
.fillMaxWidth()
.height(44.dp)
.clip(RoundedCornerShape(10.dp))
- .background(if (selected) MaterialTheme.colorScheme.surfaceVariant else Color.Transparent)
+ .background(if (selected) MaterialTheme.colorScheme.surfaceVariant else bitFunColors.transparent)
.onGloballyPositioned { coordinates ->
anchorBounds = coordinates.boundsInWindow().toIntRect()
}
@@ -252,7 +252,7 @@ private fun ArchivedDisclosureRow(count: Int, expanded: Boolean, onToggle: () ->
.padding(top = 8.dp)
.height(46.dp)
.clip(RoundedCornerShape(10.dp))
- .background(if (expanded) MaterialTheme.colorScheme.surfaceVariant else Color.Transparent)
+ .background(if (expanded) MaterialTheme.colorScheme.surfaceVariant else bitFunColors.transparent)
.clickable(role = Role.Button, onClick = onToggle)
.semantics(mergeDescendants = true) {
contentDescription = archivedLabel
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/theme/Theme.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/theme/Theme.kt
index 1012bb44ed..644f5ef927 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/theme/Theme.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/theme/Theme.kt
@@ -30,21 +30,21 @@ private val LightTokens = MobileDesignColors.Light
private val DarkTokens = MobileDesignColors.Dark
private val InkLight = LightTokens.Ink
private val InkDark = DarkTokens.Ink
-private val White = LightTokens.PrimaryActionText
+private val ContentOnAction = LightTokens.ContentOnAction
private val LightScheme = lightColorScheme(
primary = LightTokens.PrimaryAction,
- onPrimary = White, // primary_action_text
+ onPrimary = ContentOnAction,
primaryContainer = LightTokens.Soft,
onPrimaryContainer = InkLight,
secondary = LightTokens.Accent,
- onSecondary = White,
+ onSecondary = ContentOnAction,
secondaryContainer = LightTokens.Soft,
onSecondaryContainer = InkLight,
// file_link: the one saturated hue in the palette. Material has no link
// role, so it lands on tertiary — which is also the "busy" connection dot.
tertiary = LightTokens.FileLink,
- onTertiary = White,
+ onTertiary = ContentOnAction,
background = LightTokens.PageBg,
onBackground = InkLight,
surface = LightTokens.Card,
@@ -72,21 +72,22 @@ private val LightScheme = lightColorScheme(
inversePrimary = LightTokens.Line,
outline = LightTokens.Subtle,
outlineVariant = LightTokens.Line,
- error = LightTokens.Red,
- onError = White,
+ error = LightTokens.StatusDanger,
+ onError = ContentOnAction,
// The HarmonyOS palette has no error container; rather than invent a hue,
// a failure card is the same soft surface with the error colour on it.
errorContainer = LightTokens.Soft,
- onErrorContainer = LightTokens.Red,
+ onErrorContainer = LightTokens.StatusDanger,
+ scrim = LightTokens.Scrim,
)
private val DarkScheme = darkColorScheme(
primary = DarkTokens.PrimaryAction,
- onPrimary = White,
+ onPrimary = ContentOnAction,
primaryContainer = DarkTokens.Soft,
onPrimaryContainer = InkDark,
secondary = DarkTokens.Accent,
- onSecondary = White,
+ onSecondary = ContentOnAction,
secondaryContainer = DarkTokens.Soft,
onSecondaryContainer = InkDark,
tertiary = DarkTokens.FileLink,
@@ -110,10 +111,11 @@ private val DarkScheme = darkColorScheme(
inversePrimary = DarkTokens.Line,
outline = DarkTokens.Subtle,
outlineVariant = DarkTokens.Line,
- error = DarkTokens.Red,
- onError = White,
+ error = DarkTokens.StatusDanger,
+ onError = ContentOnAction,
errorContainer = DarkTokens.Soft,
- onErrorContainer = DarkTokens.Red,
+ onErrorContainer = DarkTokens.StatusDanger,
+ scrim = DarkTokens.Scrim,
)
/**
@@ -123,8 +125,17 @@ private val DarkScheme = darkColorScheme(
* because primary here is near-black ink and a black dot reads as "off".
*/
internal data class BitFunColors(
- val success: Color,
- val modalScrim: Color,
+ val transparent: Color,
+ val statusSuccess: Color,
+ val shellScrim: Color,
+ val mediaBackground: Color,
+ val mediaScrim: Color,
+ val mediaControlBackground: Color,
+ val toastBackground: Color,
+ val shadowSubtle: Color,
+ val shadowMedium: Color,
+ val shadowStrong: Color,
+ val floatingBorder: Color,
val heroBackground: Color,
val heroSurface: Color,
val heroAccent: Color,
@@ -154,8 +165,17 @@ internal data class CodeSyntaxColors(
)
private val LightExtras = BitFunColors(
- success = LightTokens.Green,
- modalScrim = LightTokens.ModalScrim,
+ transparent = LightTokens.Transparent,
+ statusSuccess = LightTokens.StatusSuccess,
+ shellScrim = LightTokens.ShellScrim,
+ mediaBackground = LightTokens.MediaBackground,
+ mediaScrim = LightTokens.MediaScrim,
+ mediaControlBackground = LightTokens.MediaControlBackground,
+ toastBackground = LightTokens.ToastBackground,
+ shadowSubtle = LightTokens.ShadowSubtle,
+ shadowMedium = LightTokens.ShadowMedium,
+ shadowStrong = LightTokens.ShadowStrong,
+ floatingBorder = LightTokens.FloatingBorder,
heroBackground = LightTokens.ConnectHeroBg,
heroSurface = LightTokens.ConnectHeroSurface,
heroAccent = LightTokens.ConnectHeroAccent,
@@ -175,8 +195,17 @@ private val LightExtras = BitFunColors(
)
private val DarkExtras = BitFunColors(
- success = DarkTokens.Green,
- modalScrim = DarkTokens.ModalScrim,
+ transparent = DarkTokens.Transparent,
+ statusSuccess = DarkTokens.StatusSuccess,
+ shellScrim = DarkTokens.ShellScrim,
+ mediaBackground = DarkTokens.MediaBackground,
+ mediaScrim = DarkTokens.MediaScrim,
+ mediaControlBackground = DarkTokens.MediaControlBackground,
+ toastBackground = DarkTokens.ToastBackground,
+ shadowSubtle = DarkTokens.ShadowSubtle,
+ shadowMedium = DarkTokens.ShadowMedium,
+ shadowStrong = DarkTokens.ShadowStrong,
+ floatingBorder = DarkTokens.FloatingBorder,
heroBackground = DarkTokens.ConnectHeroBg,
heroSurface = DarkTokens.ConnectHeroSurface,
heroAccent = DarkTokens.ConnectHeroAccent,
diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/theme/generated/MobileDesignTokens.kt b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/theme/generated/MobileDesignTokens.kt
index a6460f8f59..f3ae76fe96 100644
--- a/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/theme/generated/MobileDesignTokens.kt
+++ b/src/apps/mobile/android/app/src/main/kotlin/com/bitfun/mobile/app/ui/theme/generated/MobileDesignTokens.kt
@@ -10,6 +10,7 @@ import androidx.compose.ui.unit.sp
internal object MobileDesignColors {
object Light {
val StartWindowBackground = Color(0xFFFFFFFF)
+ val Transparent = Color(0x00000000)
val PageBg = Color(0xFFFFFFFF)
val PageBgFade = Color(0x00FFFFFF)
val Ink = Color(0xFF171717)
@@ -20,17 +21,27 @@ internal object MobileDesignColors {
val Accent = Color(0xFF111111)
val FileLink = Color(0xFF2563EB)
val PrimaryAction = Color(0xFF111111)
- val PrimaryActionText = Color(0xFFFFFFFF)
+ val ContentOnAction = Color(0xFFFFFFFF)
val ConnectHeroBg = Color(0xFFE6EDFF)
val ConnectHeroAccent = Color(0xFF9DB4FF)
val ConnectHeroSecondary = Color(0xFFC9C5FF)
val ConnectHeroSurface = Color(0xFFF8FAFF)
val ConnectScanAccent = Color(0xFFFFD021)
- val ModalScrim = Color(0x44000000)
+ val Scrim = Color(0x44000000)
+ val ShellScrim = Color(0x24000000)
+ val MediaBackground = Color(0xFF000000)
+ val MediaScrim = Color(0xB8000000)
+ val MediaControlBackground = Color(0x8C000000)
+ val ToastBackground = Color(0xD1171717)
+ val ShadowFaint = Color(0x08000000)
+ val ShadowSubtle = Color(0x12000000)
+ val ShadowMedium = Color(0x18000000)
+ val ShadowStrong = Color(0x24000000)
+ val FloatingBorder = Color(0x18000000)
val Soft = Color(0xFFF4F3F0)
val FloatingPanelBg = Color(0xFFF7F7F5)
- val Green = Color(0xFF27C46A)
- val Red = Color(0xFFE04F4F)
+ val StatusSuccess = Color(0xFF27C46A)
+ val StatusDanger = Color(0xFFE04F4F)
val CodeLineNumber = Color(0xFFAAA69D)
val CodeKeyword = Color(0xFF8F3F71)
val CodeString = Color(0xFF477A4A)
@@ -45,6 +56,7 @@ internal object MobileDesignColors {
object Dark {
val StartWindowBackground = Color(0xFF000000)
+ val Transparent = Color(0x00000000)
val PageBg = Color(0xFF151514)
val PageBgFade = Color(0x00151514)
val Ink = Color(0xFFF4F3EF)
@@ -55,17 +67,27 @@ internal object MobileDesignColors {
val Accent = Color(0xFF5B5954)
val FileLink = Color(0xFF60A5FA)
val PrimaryAction = Color(0xFF454540)
- val PrimaryActionText = Color(0xFFFFFFFF)
+ val ContentOnAction = Color(0xFFFFFFFF)
val ConnectHeroBg = Color(0xFF2B2B29)
val ConnectHeroAccent = Color(0xFF4A4944)
val ConnectHeroSecondary = Color(0xFF3C3B38)
val ConnectHeroSurface = Color(0xFF252522)
val ConnectScanAccent = Color(0xFFFFD021)
- val ModalScrim = Color(0x44000000)
+ val Scrim = Color(0x44000000)
+ val ShellScrim = Color(0x24000000)
+ val MediaBackground = Color(0xFF000000)
+ val MediaScrim = Color(0xB8000000)
+ val MediaControlBackground = Color(0x8C000000)
+ val ToastBackground = Color(0xD1171717)
+ val ShadowFaint = Color(0x08000000)
+ val ShadowSubtle = Color(0x12000000)
+ val ShadowMedium = Color(0x18000000)
+ val ShadowStrong = Color(0x24000000)
+ val FloatingBorder = Color(0x18000000)
val Soft = Color(0xFF2D2C28)
val FloatingPanelBg = Color(0xFF1E1E1C)
- val Green = Color(0xFF3BD47B)
- val Red = Color(0xFFFF6B6B)
+ val StatusSuccess = Color(0xFF3BD47B)
+ val StatusDanger = Color(0xFFFF6B6B)
val CodeLineNumber = Color(0xFF77756E)
val CodeKeyword = Color(0xFFD99AC4)
val CodeString = Color(0xFF9BCB9D)
diff --git a/src/apps/mobile/design-system/components/mobile-components.json b/src/apps/mobile/design-system/components/mobile-components.json
index b34ef604b9..66f1945e78 100644
--- a/src/apps/mobile/design-system/components/mobile-components.json
+++ b/src/apps/mobile/design-system/components/mobile-components.json
@@ -12,7 +12,7 @@
"purpose": "Expresses one primary, secondary, quiet, or destructive workflow action with consistent emphasis.",
"anatomy": ["touch_target", "action_label", "semantic_surface", "optional_hairline_border"],
"states": ["primary", "secondary", "quiet", "destructive", "disabled", "busy"],
- "tokens": ["sheet_action_height", "primary_action", "primary_action_text", "card", "soft", "line", "red", "label_large"],
+ "tokens": ["sheet_action_height", "primary_action", "content_on_action", "card", "soft", "line", "status_danger", "label_large"],
"platformNotes": "The semantic style is shared; a workflow may override height when its context requires a larger target, while preserving typography, radius, color, and disabled treatment."
},
"conversation_header": {
@@ -45,9 +45,9 @@
},
"adaptive_modal_surface": {
"purpose": "Hosts settings, connection, creation, selection, and detail flows without crossing a physical fold or obscuring more of the workspace than necessary.",
- "anatomy": ["modal_scrim", "paper_surface", "header", "scroll_content", "action_rail"],
+ "anatomy": ["scrim", "paper_surface", "header", "scroll_content", "action_rail"],
"states": ["compact_bottom", "wide_side", "fold_operate", "busy", "error"],
- "tokens": ["modal_scrim", "sheet_top_radius", "sheet_side_radius", "sheet_horizontal_padding", "sheet_header_height", "sheet_action_height", "card", "line", "structure"],
+ "tokens": ["scrim", "sheet_top_radius", "sheet_side_radius", "sheet_horizontal_padding", "sheet_header_height", "sheet_action_height", "card", "line", "structure"],
"platformNotes": "Use each platform's native modal lifecycle, accessibility focus, and back gesture; placement comes from the shared adaptive policy and visual geometry comes from these tokens."
},
"action_popover": {
@@ -61,7 +61,7 @@
"purpose": "Presents actions for a session row without stacking confirmation UI.",
"anatomy": ["optional_drag_handle", "session_identity", "action_rows", "in_place_confirmation"],
"states": ["compact_bottom", "wide_popover", "confirming_delete", "busy"],
- "tokens": ["sheet_action_height", "popover_radius", "card", "line", "soft", "red"],
+ "tokens": ["sheet_action_height", "popover_radius", "card", "line", "soft", "status_danger"],
"platformNotes": "Compact session lists use a transparent native sheet hosting the same 16-unit paper surface that wide lists anchor as a popover; deletion confirmation replaces the action rows in place. This is distinct from the active conversation header's action_popover."
},
"selection_surface": {
@@ -75,7 +75,7 @@
"purpose": "Confirms destructive or high-impact actions inside the surface that initiated them.",
"anatomy": ["specific_consequence", "cancel_action", "destructive_action"],
"states": ["idle", "confirming", "submitting", "failed"],
- "tokens": ["sheet_action_height", "red", "soft", "line"],
+ "tokens": ["sheet_action_height", "status_danger", "soft", "line"],
"platformNotes": "Prefer an in-place confirmation step over stacking a second modal and a second scrim."
},
"settings_card": {
@@ -103,7 +103,7 @@
"purpose": "Guides desktop pairing from preparation through scanning, with a manual-code fallback that stays inside the connect surface.",
"anatomy": ["hero_wash", "back_control", "desktop_or_scanner_glyph", "instructions", "primary_action", "manual_pairing_overlay", "conditional_account_credentials", "status_feedback"],
"states": ["intro", "scan", "manual", "account_auth", "connecting", "failed", "paired"],
- "tokens": ["connect_hero_bg", "connect_hero_surface", "modal_scrim", "sheet_side_radius", "primary_action", "card", "soft", "line"],
+ "tokens": ["connect_hero_bg", "connect_hero_surface", "scrim", "sheet_side_radius", "primary_action", "card", "soft", "line"],
"platformNotes": "Camera capture and permission prompts remain native. The manual form is an in-surface overlay with the shared scrim and 34-unit card, not a second system sheet. Account-protected links add username and password fields in that same card; passwords remain transient view state and are cleared on submit or dismiss."
},
"remote_create_surface": {
@@ -117,7 +117,7 @@
"purpose": "Explains which desktop is being controlled, how it is connected, and which permission policy that desktop applies.",
"anatomy": ["modal_header", "profile_entry", "current_control_card", "connection_source", "alternate_connection_entry", "permission_mode_card", "in_place_full_access_confirmation"],
"states": ["disconnected", "connecting", "connected_by_account", "connected_by_pairing", "permission_loading", "permission_failed", "confirming_full_access", "account_page"],
- "tokens": ["sheet_header_height", "settings_prominent_card_radius", "settings_compact_card_radius", "modal_scrim", "card", "soft", "line", "red"],
+ "tokens": ["sheet_header_height", "settings_prominent_card_radius", "settings_compact_card_radius", "scrim", "card", "soft", "line", "status_danger"],
"platformNotes": "The account page replaces this page inside the same adaptive modal. Full-access confirmation replaces content inside the permission card; it never opens a system alert or a second sheet."
},
"file_preview_surface": {
diff --git a/src/apps/mobile/design-system/preview/generated/mobile-design-data.js b/src/apps/mobile/design-system/preview/generated/mobile-design-data.js
index ae3635f005..9536156582 100644
--- a/src/apps/mobile/design-system/preview/generated/mobile-design-data.js
+++ b/src/apps/mobile/design-system/preview/generated/mobile-design-data.js
@@ -10,6 +10,10 @@ export const mobileTokens = {
"light": "#FFFFFF",
"dark": "#000000"
},
+ "transparent": {
+ "light": "#00000000",
+ "dark": "#00000000"
+ },
"page_bg": {
"light": "#FFFFFF",
"dark": "#151514"
@@ -50,7 +54,7 @@ export const mobileTokens = {
"light": "#111111",
"dark": "#454540"
},
- "primary_action_text": {
+ "content_on_action": {
"light": "#FFFFFF",
"dark": "#FFFFFF"
},
@@ -74,10 +78,50 @@ export const mobileTokens = {
"light": "#FFD021",
"dark": "#FFD021"
},
- "modal_scrim": {
+ "scrim": {
"light": "#44000000",
"dark": "#44000000"
},
+ "shell_scrim": {
+ "light": "#24000000",
+ "dark": "#24000000"
+ },
+ "media_background": {
+ "light": "#FF000000",
+ "dark": "#FF000000"
+ },
+ "media_scrim": {
+ "light": "#B8000000",
+ "dark": "#B8000000"
+ },
+ "media_control_background": {
+ "light": "#8C000000",
+ "dark": "#8C000000"
+ },
+ "toast_background": {
+ "light": "#D1171717",
+ "dark": "#D1171717"
+ },
+ "shadow_faint": {
+ "light": "#08000000",
+ "dark": "#08000000"
+ },
+ "shadow_subtle": {
+ "light": "#12000000",
+ "dark": "#12000000"
+ },
+ "shadow_medium": {
+ "light": "#18000000",
+ "dark": "#18000000"
+ },
+ "shadow_strong": {
+ "light": "#24000000",
+ "dark": "#24000000"
+ },
+ "floating_border": {
+ "light": "#18000000",
+ "dark": "#18000000"
+ },
"soft": {
"light": "#F4F3F0",
"dark": "#2D2C28"
@@ -86,11 +130,11 @@ export const mobileTokens = {
"light": "#F7F7F5",
"dark": "#1E1E1C"
},
- "green": {
+ "status_success": {
"light": "#27C46A",
"dark": "#3BD47B"
},
- "red": {
+ "status_danger": {
"light": "#E04F4F",
"dark": "#FF6B6B"
},
@@ -328,11 +372,11 @@ export const mobileComponents = {
"tokens": [
"sheet_action_height",
"primary_action",
- "primary_action_text",
+ "content_on_action",
"card",
"soft",
"line",
- "red",
+ "status_danger",
"label_large"
],
"platformNotes": "The semantic style is shared; a workflow may override height when its context requires a larger target, while preserving typography, radius, color, and disabled treatment."
@@ -443,7 +487,7 @@ export const mobileComponents = {
"adaptive_modal_surface": {
"purpose": "Hosts settings, connection, creation, selection, and detail flows without crossing a physical fold or obscuring more of the workspace than necessary.",
"anatomy": [
- "modal_scrim",
+ "scrim",
"paper_surface",
"header",
"scroll_content",
@@ -457,7 +501,7 @@ export const mobileComponents = {
"error"
],
"tokens": [
- "modal_scrim",
+ "scrim",
"sheet_top_radius",
"sheet_side_radius",
"sheet_horizontal_padding",
@@ -519,7 +563,7 @@ export const mobileComponents = {
"card",
"line",
"soft",
- "red"
+ "status_danger"
],
"platformNotes": "Compact session lists use a transparent native sheet hosting the same 16-unit paper surface that wide lists anchor as a popover; deletion confirmation replaces the action rows in place. This is distinct from the active conversation header's action_popover."
},
@@ -565,7 +609,7 @@ export const mobileComponents = {
],
"tokens": [
"sheet_action_height",
- "red",
+ "status_danger",
"soft",
"line"
],
@@ -683,7 +727,7 @@ export const mobileComponents = {
"tokens": [
"connect_hero_bg",
"connect_hero_surface",
- "modal_scrim",
+ "scrim",
"sheet_side_radius",
"primary_action",
"card",
@@ -748,11 +792,11 @@ export const mobileComponents = {
"sheet_header_height",
"settings_prominent_card_radius",
"settings_compact_card_radius",
- "modal_scrim",
+ "scrim",
"card",
"soft",
"line",
- "red"
+ "status_danger"
],
"platformNotes": "The account page replaces this page inside the same adaptive modal. Full-access confirmation replaces content inside the permission card; it never opens a system alert or a second sheet."
},
diff --git a/src/apps/mobile/design-system/preview/index.html b/src/apps/mobile/design-system/preview/index.html
index 113418417e..5fbd430c07 100644
--- a/src/apps/mobile/design-system/preview/index.html
+++ b/src/apps/mobile/design-system/preview/index.html
@@ -1,9 +1,11 @@
-
+
BitFun Mobile Parity Bench
+
+
diff --git a/src/apps/mobile/design-system/preview/preview.css b/src/apps/mobile/design-system/preview/preview.css
index fd8d1f8c40..33fe204b36 100644
--- a/src/apps/mobile/design-system/preview/preview.css
+++ b/src/apps/mobile/design-system/preview/preview.css
@@ -1,8 +1,8 @@
:root {
color-scheme: light;
- font-family: Inter, "SF Pro Text", "HarmonyOS Sans", system-ui, sans-serif;
- background: #efeee9;
- color: #171717;
+ font-family: var(--bf-font-family-sans);
+ background: var(--bf-color-surface-workbench);
+ color: var(--bf-color-content-primary);
}
* { box-sizing: border-box; }
@@ -12,8 +12,8 @@ body {
min-width: 1040px;
min-height: 100vh;
background:
- linear-gradient(#0000 31px, rgb(23 23 23 / 0.035) 32px),
- #efeee9;
+ linear-gradient(transparent 31px, color-mix(in srgb, var(--bf-color-content-primary) 3.5%, transparent) 32px),
+ var(--bf-color-surface-workbench);
background-size: 100% 32px;
}
@@ -35,8 +35,8 @@ button, input, select { font: inherit; }
.eyebrow {
margin: 0 0 11px;
- color: #706f6a;
- font: 600 11px/1.2 ui-monospace, "SFMono-Regular", monospace;
+ color: var(--bf-color-content-muted);
+ font: 600 11px/1.2 var(--bf-font-family-mono);
letter-spacing: 0.13em;
}
@@ -50,7 +50,7 @@ h1 {
.intro {
max-width: 720px;
margin: 13px 0 0;
- color: #595853;
+ color: var(--bf-color-content-secondary);
font-size: 14px;
line-height: 1.7;
}
@@ -60,19 +60,19 @@ h1 {
align-items: center;
gap: 9px;
padding: 9px 12px;
- border: 1px solid #d9d7d1;
+ border: 1px solid var(--bf-color-border-default);
border-radius: 999px;
- background: #f7f7f5;
- color: #4b4a46;
- font: 600 11px/1 ui-monospace, monospace;
+ background: var(--bf-color-surface-panel);
+ color: var(--bf-color-content-secondary);
+ font: 600 11px/1 var(--bf-font-family-mono);
}
.baseline-key span {
width: 8px;
height: 8px;
border-radius: 50%;
- background: #2563eb;
- box-shadow: 0 0 0 4px rgb(37 99 235 / 0.13);
+ background: var(--bf-color-link-default);
+ box-shadow: 0 0 0 4px color-mix(in srgb, var(--bf-color-link-default) 13%, transparent);
}
.toolbar {
@@ -81,9 +81,9 @@ h1 {
gap: 18px;
align-items: end;
padding: 18px 20px;
- border: 1px solid #d9d7d1;
+ border: 1px solid var(--bf-color-border-default);
border-radius: 18px 18px 0 0;
- background: rgb(253 253 251 / 0.9);
+ background: color-mix(in srgb, var(--bf-color-surface-panel) 90%, transparent);
backdrop-filter: blur(16px);
}
@@ -93,8 +93,8 @@ h1 {
}
.toolbar label > span {
- color: #706f6a;
- font: 600 11px/1.2 ui-monospace, monospace;
+ color: var(--bf-color-content-muted);
+ font: 600 11px/1.2 var(--bf-font-family-mono);
letter-spacing: 0.05em;
}
@@ -102,10 +102,10 @@ select {
width: 100%;
height: 38px;
padding: 0 34px 0 12px;
- border: 1px solid #d9d7d1;
+ border: 1px solid var(--bf-color-field-border);
border-radius: 10px;
- background: #fff;
- color: #171717;
+ background: var(--bf-color-field-background);
+ color: var(--bf-color-content-primary);
}
.range-control {
@@ -113,8 +113,8 @@ select {
}
.range-control span { grid-column: 1 / -1; }
-.range-control input { width: 100%; accent-color: #171717; }
-.range-control output { color: #706f6a; font: 12px ui-monospace, monospace; }
+.range-control input { width: 100%; accent-color: var(--bf-color-accent-default); }
+.range-control output { color: var(--bf-color-content-muted); font: 12px var(--bf-font-family-mono); }
.check-control {
display: flex;
@@ -124,7 +124,7 @@ select {
white-space: nowrap;
}
-.check-control input { width: 16px; height: 16px; accent-color: #171717; }
+.check-control input { width: 16px; height: 16px; accent-color: var(--bf-color-accent-default); }
.scenario-note {
display: flex;
@@ -132,14 +132,14 @@ select {
align-items: baseline;
min-height: 46px;
padding: 14px 20px;
- border: 1px solid #d9d7d1;
+ border: 1px solid var(--bf-color-border-default);
border-top: 0;
- background: #f7f7f5;
- color: #706f6a;
+ background: var(--bf-color-surface-panel);
+ color: var(--bf-color-content-muted);
font-size: 12px;
}
-.scenario-note strong { color: #171717; }
+.scenario-note strong { color: var(--bf-color-content-primary); }
.platform-grid {
display: grid;
@@ -151,13 +151,13 @@ select {
.platform-card {
min-width: 0;
overflow: hidden;
- border: 1px solid #d3d1cb;
+ border: 1px solid var(--bf-color-border-default);
border-radius: 20px;
- background: #fdfdfb;
- box-shadow: 0 18px 50px rgb(23 23 23 / 0.07);
+ background: var(--bf-color-surface-panel);
+ box-shadow: var(--bf-shadow-overlay);
}
-.platform-card[data-platform="harmonyos"] { border-top: 3px solid #2563eb; }
+.platform-card[data-platform="harmonyos"] { border-top: 3px solid var(--bf-color-link-default); }
.platform-heading {
display: flex;
@@ -165,7 +165,7 @@ select {
gap: 10px;
min-height: 62px;
padding: 12px 15px;
- border-bottom: 1px solid #e9e7e2;
+ border-bottom: 1px solid var(--bf-color-border-subtle);
}
.platform-mark {
@@ -174,29 +174,29 @@ select {
width: 34px;
height: 34px;
border-radius: 10px;
- background: #171717;
- color: #fff;
- font: 700 12px/1 ui-monospace, monospace;
+ background: var(--bf-color-action-primary-background);
+ color: var(--bf-color-action-primary-content);
+ font: 700 12px/1 var(--bf-font-family-mono);
}
-.platform-card[data-platform="harmonyos"] .platform-mark { background: #2563eb; }
+.platform-card[data-platform="harmonyos"] .platform-mark { background: var(--bf-color-link-default); }
.platform-title { min-width: 0; }
.platform-title strong { display: block; font-size: 13px; }
-.platform-title span { display: block; margin-top: 3px; color: #7d7b75; font-size: 10px; }
+.platform-title span { display: block; margin-top: 3px; color: var(--bf-color-content-muted); font-size: 10px; }
.capture-button {
margin-left: auto;
padding: 8px 10px;
- border: 1px solid #d9d7d1;
+ border: 1px solid var(--bf-color-border-default);
border-radius: 9px;
- background: #fff;
- color: #45443f;
+ background: var(--bf-color-field-background);
+ color: var(--bf-color-content-secondary);
cursor: pointer;
font-size: 11px;
}
-.capture-button:hover { border-color: #a5a39b; }
+.capture-button:hover { border-color: var(--bf-color-field-border-hover); }
.capture-button input { display: none; }
.viewport-stage {
@@ -206,7 +206,7 @@ select {
min-height: 690px;
padding: 22px;
overflow: hidden;
- background: #e9e7e2;
+ background: var(--bf-color-surface-subtle);
}
.device-screen {
@@ -216,11 +216,11 @@ select {
aspect-ratio: var(--viewport-width) / var(--viewport-height);
max-height: 646px;
overflow: hidden;
- border: 1px solid rgb(23 23 23 / 0.25);
+ border: 1px solid color-mix(in srgb, var(--bf-color-content-primary) 25%, transparent);
border-radius: 28px;
- background: var(--page-bg);
- color: var(--ink);
- box-shadow: 0 20px 60px rgb(23 23 23 / 0.18);
+ background: var(--mobile-page-bg);
+ color: var(--mobile-ink);
+ box-shadow: var(--bf-shadow-overlay);
container-type: inline-size;
}
@@ -245,111 +245,111 @@ select {
display: flex;
align-items: center;
gap: 6px;
- height: calc(var(--connection-strip-height) * 1px);
- padding: 0 calc(var(--content-gutter) * 1px);
- border-bottom: 1px solid var(--line);
+ height: calc(var(--mobile-connection-strip-height) * 1px);
+ padding: 0 calc(var(--mobile-content-gutter) * 1px);
+ border-bottom: 1px solid var(--mobile-line);
font-size: 11px;
}
.screen-meta strong { font-size: 12px; }
-.screen-meta span { margin-left: auto; color: var(--muted); font-family: ui-monospace, monospace; font-size: 9px; }
+.screen-meta span { margin-left: auto; color: var(--mobile-muted); font-family: ui-monospace, monospace; font-size: 9px; }
.conversation-header {
display: grid;
- grid-template-columns: calc(var(--control-touch-size) * 1px) 1fr calc(var(--control-touch-size) * 1px);
+ grid-template-columns: calc(var(--mobile-control-touch-size) * 1px) 1fr calc(var(--mobile-control-touch-size) * 1px);
align-items: center;
gap: 8px;
- height: calc(var(--conversation-header-height) * 1px);
- padding: 8px calc(var(--content-gutter) * 1px);
+ height: calc(var(--mobile-conversation-header-height) * 1px);
+ padding: 8px calc(var(--mobile-content-gutter) * 1px);
}
.circle-control {
display: grid;
place-items: center;
- width: calc(var(--control-touch-size) * 1px);
- height: calc(var(--control-touch-size) * 1px);
- border: 1px solid var(--line);
+ width: calc(var(--mobile-control-touch-size) * 1px);
+ height: calc(var(--mobile-control-touch-size) * 1px);
+ border: 1px solid var(--mobile-line);
border-radius: 50%;
- background: var(--card);
- box-shadow: 0 3px 10px rgb(23 23 23 / 0.08);
- color: var(--ink);
+ background: var(--mobile-card);
+ box-shadow: 0 3px 10px var(--mobile-shadow-medium);
+ color: var(--mobile-ink);
font-size: 18px;
}
.header-copy { min-width: 0; text-align: center; }
.header-copy strong, .header-copy span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.header-copy strong {
- font-size: calc(var(--conversation-header-title-size) * 1px);
- line-height: calc(var(--conversation-header-title-line-height) * 1px);
- font-weight: var(--conversation-header-title-weight);
+ font-size: calc(var(--mobile-conversation-header-title-size) * 1px);
+ line-height: calc(var(--mobile-conversation-header-title-line-height) * 1px);
+ font-weight: var(--mobile-conversation-header-title-weight);
}
.header-copy span {
margin-top: 3px;
- color: var(--muted);
- font-size: calc(var(--label-medium-size) * 1px);
- line-height: calc(var(--label-medium-line-height) * 1px);
- font-weight: var(--label-medium-weight);
+ color: var(--mobile-muted);
+ font-size: calc(var(--mobile-label-medium-size) * 1px);
+ line-height: calc(var(--mobile-label-medium-line-height) * 1px);
+ font-weight: var(--mobile-label-medium-weight);
}
.timeline {
flex: 1;
display: flex;
flex-direction: column;
- gap: calc(var(--message-spacing) * 1px);
+ gap: calc(var(--mobile-message-spacing) * 1px);
min-height: 0;
- padding: calc(var(--timeline-top-padding) * 1px) calc(var(--content-gutter) * 1px);
+ padding: calc(var(--mobile-timeline-top-padding) * 1px) calc(var(--mobile-content-gutter) * 1px);
}
.message {
- max-width: calc(var(--message-bubble-max-width) * 1px);
+ max-width: calc(var(--mobile-message-bubble-max-width) * 1px);
padding:
- calc(var(--message-bubble-vertical-padding) * 1px)
- calc(var(--message-bubble-horizontal-padding) * 1px);
- border: 1px solid var(--line);
- border-radius: calc(var(--message-bubble-radius) * 1px);
- background: var(--card);
- font-size: calc(var(--body-medium-size) * 1px);
- line-height: calc(var(--body-medium-line-height) * 1px);
- font-weight: var(--body-medium-weight);
+ calc(var(--mobile-message-bubble-vertical-padding) * 1px)
+ calc(var(--mobile-message-bubble-horizontal-padding) * 1px);
+ border: 1px solid var(--mobile-line);
+ border-radius: calc(var(--mobile-message-bubble-radius) * 1px);
+ background: var(--mobile-card);
+ font-size: calc(var(--mobile-body-medium-size) * 1px);
+ line-height: calc(var(--mobile-body-medium-line-height) * 1px);
+ font-weight: var(--mobile-body-medium-weight);
}
-.message.user { align-self: flex-end; background: var(--soft); }
+.message.user { align-self: flex-end; background: var(--mobile-soft); }
.connection-note {
align-self: center;
padding: 5px 9px;
border-radius: 999px;
- background: var(--soft);
- color: var(--muted);
+ background: var(--mobile-soft);
+ color: var(--mobile-muted);
font: 10px/1.2 ui-monospace, monospace;
}
-.composer-zone { padding: 8px calc(var(--content-gutter) * 1px) 14px; }
+.composer-zone { padding: 8px calc(var(--mobile-content-gutter) * 1px) 14px; }
.composer {
display: grid;
- grid-template-columns: calc(var(--composer-action-size) * 1px) 1fr calc(var(--composer-action-size) * 1px);
+ grid-template-columns: calc(var(--mobile-composer-action-size) * 1px) 1fr calc(var(--mobile-composer-action-size) * 1px);
align-items: center;
gap: 5px;
- min-height: calc(var(--composer-collapsed-height) * 1px);
+ min-height: calc(var(--mobile-composer-collapsed-height) * 1px);
padding: 0 8px;
border: 0;
- border-radius: calc(var(--composer-collapsed-radius) * 1px);
- background: var(--card);
- box-shadow: 0 2px 10px rgb(23 23 23 / 0.08);
+ border-radius: calc(var(--mobile-composer-collapsed-radius) * 1px);
+ background: var(--mobile-card);
+ box-shadow: 0 2px 10px var(--mobile-shadow-medium);
}
-.composer.has-draft { min-height: 76px; border-radius: calc(var(--composer-expanded-radius) * 1px); }
-.composer button { width: 40px; height: 40px; border: 0; background: transparent; color: var(--ink); font-size: 19px; }
+.composer.has-draft { min-height: 76px; border-radius: calc(var(--mobile-composer-expanded-radius) * 1px); }
+.composer button { width: 40px; height: 40px; border: 0; background: transparent; color: var(--mobile-ink); font-size: 19px; }
.composer-copy {
min-width: 0;
- color: var(--muted);
- font-size: calc(var(--body-large-size) * 1px);
- line-height: calc(var(--body-large-line-height) * 1px);
- font-weight: var(--body-large-weight);
+ color: var(--mobile-muted);
+ font-size: calc(var(--mobile-body-large-size) * 1px);
+ line-height: calc(var(--mobile-body-large-line-height) * 1px);
+ font-weight: var(--mobile-body-large-weight);
}
-.composer.has-draft .composer-copy { color: var(--ink); }
-.composer .primary { border-radius: 50%; background: var(--primary-action); color: var(--primary-action-text); }
+.composer.has-draft .composer-copy { color: var(--mobile-ink); }
+.composer .primary { border-radius: 50%; background: var(--mobile-primary-action); color: var(--mobile-content-on-action); }
.native-shot {
position: absolute;
@@ -359,8 +359,8 @@ select {
width: 100%;
height: 100%;
object-fit: contain;
- background: #111;
- opacity: var(--native-opacity, 1);
+ background: var(--mobile-media-background);
+ opacity: var(--native-opacity);
}
.device-screen.has-native .native-shot { display: block; }
@@ -372,8 +372,8 @@ select {
z-index: 5;
display: none;
background-image:
- linear-gradient(rgb(37 99 235 / 0.2) 1px, transparent 1px),
- linear-gradient(90deg, rgb(37 99 235 / 0.14) 1px, transparent 1px);
+ linear-gradient(color-mix(in srgb, var(--bf-color-link-default) 20%, transparent) 1px, transparent 1px),
+ linear-gradient(90deg, color-mix(in srgb, var(--bf-color-link-default) 14%, transparent) 1px, transparent 1px);
background-size: 8px 8px;
}
@@ -384,20 +384,20 @@ select {
grid-template-columns: auto 1fr;
gap: 12px;
padding: 10px 15px;
- border-top: 1px solid #e9e7e2;
- color: #77756e;
- font: 10px/1.4 ui-monospace, monospace;
+ border-top: 1px solid var(--bf-color-border-subtle);
+ color: var(--bf-color-content-muted);
+ font: 10px/1.4 var(--bf-font-family-mono);
}
-.capture-status strong { color: #45443f; }
+.capture-status strong { color: var(--bf-color-content-secondary); }
.capture-status span { text-align: right; }
.capture-status em {
grid-column: 1 / -1;
- color: #706f6a;
+ color: var(--bf-color-content-muted);
font-style: normal;
text-align: right;
}
-.capture-aspect-warning .capture-status strong { color: #9a5b13; }
+.capture-aspect-warning .capture-status strong { color: var(--bf-color-status-warning-content); }
@media (max-width: 1180px) {
.bench-shell { padding-inline: 20px; }
diff --git a/src/apps/mobile/design-system/preview/preview.js b/src/apps/mobile/design-system/preview/preview.js
index 51c4358329..f9d4e4002f 100644
--- a/src/apps/mobile/design-system/preview/preview.js
+++ b/src/apps/mobile/design-system/preview/preview.js
@@ -125,13 +125,13 @@ function platformCard(platform, scenario, appearance) {
function applyTokens(element, appearance) {
for (const [name, pair] of Object.entries(mobileTokens.colors)) {
- element.style.setProperty(`--${name.replaceAll('_', '-')}`, pair[appearance]);
+ element.style.setProperty(`--mobile-${name.replaceAll('_', '-')}`, mobileColorToCss(pair[appearance]));
}
for (const [name, value] of Object.entries(mobileTokens.geometry)) {
- element.style.setProperty(`--${name.replaceAll('_', '-')}`, String(value));
+ element.style.setProperty(`--mobile-${name.replaceAll('_', '-')}`, String(value));
}
for (const [name, token] of Object.entries(mobileTokens.typography)) {
- const prefix = `--${name.replaceAll('_', '-')}`;
+ const prefix = `--mobile-${name.replaceAll('_', '-')}`;
element.style.setProperty(`${prefix}-size`, String(token.size));
element.style.setProperty(`${prefix}-line-height`, String(token.lineHeight));
element.style.setProperty(`${prefix}-weight`, String(token.weight));
@@ -203,7 +203,7 @@ function containedPixels(image, width, height) {
canvas.width = width;
canvas.height = height;
const context = canvas.getContext('2d', { willReadFrequently: true });
- context.fillStyle = '#111111';
+ context.fillStyle = mobileColorToCss(mobileTokens.colors.media_background.dark);
context.fillRect(0, 0, width, height);
const scale = Math.min(width / image.naturalWidth, height / image.naturalHeight);
const drawWidth = image.naturalWidth * scale;
@@ -211,3 +211,10 @@ function containedPixels(image, width, height) {
context.drawImage(image, (width - drawWidth) / 2, (height - drawHeight) / 2, drawWidth, drawHeight);
return context.getImageData(0, 0, width, height).data;
}
+
+function mobileColorToCss(value) {
+ if (!/^#[0-9A-F]{8}$/i.test(value)) return value;
+ const alpha = value.slice(1, 3);
+ const rgb = value.slice(3);
+ return `#${rgb}${alpha}`;
+}
diff --git a/src/apps/mobile/design-system/tokens/mobile-tokens.json b/src/apps/mobile/design-system/tokens/mobile-tokens.json
index 2b9e730d86..e5ea9f26ab 100644
--- a/src/apps/mobile/design-system/tokens/mobile-tokens.json
+++ b/src/apps/mobile/design-system/tokens/mobile-tokens.json
@@ -6,6 +6,7 @@
},
"colors": {
"start_window_background": { "light": "#FFFFFF", "dark": "#000000" },
+ "transparent": { "light": "#00000000", "dark": "#00000000" },
"page_bg": { "light": "#FFFFFF", "dark": "#151514" },
"page_bg_fade": { "light": "#00FFFFFF", "dark": "#00151514" },
"ink": { "light": "#171717", "dark": "#F4F3EF" },
@@ -16,17 +17,27 @@
"accent": { "light": "#111111", "dark": "#5B5954" },
"file_link": { "light": "#2563EB", "dark": "#60A5FA" },
"primary_action": { "light": "#111111", "dark": "#454540" },
- "primary_action_text": { "light": "#FFFFFF", "dark": "#FFFFFF" },
+ "content_on_action": { "light": "#FFFFFF", "dark": "#FFFFFF" },
"connect_hero_bg": { "light": "#E6EDFF", "dark": "#2B2B29" },
"connect_hero_accent": { "light": "#9DB4FF", "dark": "#4A4944" },
"connect_hero_secondary": { "light": "#C9C5FF", "dark": "#3C3B38" },
"connect_hero_surface": { "light": "#F8FAFF", "dark": "#252522" },
"connect_scan_accent": { "light": "#FFD021", "dark": "#FFD021" },
- "modal_scrim": { "light": "#44000000", "dark": "#44000000" },
+ "scrim": { "light": "#44000000", "dark": "#44000000" },
+ "shell_scrim": { "light": "#24000000", "dark": "#24000000" },
+ "media_background": { "light": "#FF000000", "dark": "#FF000000" },
+ "media_scrim": { "light": "#B8000000", "dark": "#B8000000" },
+ "media_control_background": { "light": "#8C000000", "dark": "#8C000000" },
+ "toast_background": { "light": "#D1171717", "dark": "#D1171717" },
+ "shadow_faint": { "light": "#08000000", "dark": "#08000000" },
+ "shadow_subtle": { "light": "#12000000", "dark": "#12000000" },
+ "shadow_medium": { "light": "#18000000", "dark": "#18000000" },
+ "shadow_strong": { "light": "#24000000", "dark": "#24000000" },
+ "floating_border": { "light": "#18000000", "dark": "#18000000" },
"soft": { "light": "#F4F3F0", "dark": "#2D2C28" },
"floating_panel_bg": { "light": "#F7F7F5", "dark": "#1E1E1C" },
- "green": { "light": "#27C46A", "dark": "#3BD47B" },
- "red": { "light": "#E04F4F", "dark": "#FF6B6B" },
+ "status_success": { "light": "#27C46A", "dark": "#3BD47B" },
+ "status_danger": { "light": "#E04F4F", "dark": "#FF6B6B" },
"code_line_number": { "light": "#AAA69D", "dark": "#77756E" },
"code_keyword": { "light": "#8F3F71", "dark": "#D99AC4" },
"code_string": { "light": "#477A4A", "dark": "#9BCB9D" },
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/entryability/EntryAbility.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/entryability/EntryAbility.ets
index 558a1305a7..a343768a06 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/entryability/EntryAbility.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/entryability/EntryAbility.ets
@@ -1,6 +1,7 @@
import { AbilityConstant, Configuration, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
+import { MobileDesignColors } from '../generated/MobileDesignTokens';
const DOMAIN = 0x0000;
const TAG = 'BitFunRemote';
@@ -87,12 +88,14 @@ export default class EntryAbility extends UIAbility {
return;
}
const dark = colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
+ const background = dark ? MobileDesignColors.pageBg.dark : MobileDesignColors.pageBg.light;
+ const content = dark ? MobileDesignColors.ink.dark : MobileDesignColors.ink.light;
try {
this.mainWindow.setWindowSystemBarProperties({
- statusBarColor: dark ? '#151514' : '#FDFDFB',
- navigationBarColor: dark ? '#151514' : '#FDFDFB',
- statusBarContentColor: dark ? '#F4F3EF' : '#171717',
- navigationBarContentColor: dark ? '#F4F3EF' : '#171717'
+ statusBarColor: background,
+ navigationBarColor: background,
+ statusBarContentColor: content,
+ navigationBarContentColor: content
});
} catch (err) {
hilog.error(DOMAIN, TAG, 'Failed to update system bars. Cause: %{public}s', JSON.stringify(err));
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/generated/MobileDesignTokens.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/generated/MobileDesignTokens.ets
index 163d78917d..a8363f8486 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/generated/MobileDesignTokens.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/generated/MobileDesignTokens.ets
@@ -1,5 +1,61 @@
// Generated by scripts/mobile-ui-design-system.mjs. Do not edit.
+export class MobileColorPair {
+ readonly light: string;
+ readonly dark: string;
+
+ constructor(light: string, dark: string) {
+ this.light = light;
+ this.dark = dark;
+ }
+}
+
+export class MobileDesignColors {
+ static readonly startWindowBackground: MobileColorPair = new MobileColorPair("#FFFFFF", "#000000");
+ static readonly transparent: MobileColorPair = new MobileColorPair("#00000000", "#00000000");
+ static readonly pageBg: MobileColorPair = new MobileColorPair("#FFFFFF", "#151514");
+ static readonly pageBgFade: MobileColorPair = new MobileColorPair("#00FFFFFF", "#00151514");
+ static readonly ink: MobileColorPair = new MobileColorPair("#171717", "#F4F3EF");
+ static readonly muted: MobileColorPair = new MobileColorPair("#706F6A", "#AAA8A0");
+ static readonly subtle: MobileColorPair = new MobileColorPair("#A5A39B", "#77756E");
+ static readonly line: MobileColorPair = new MobileColorPair("#E9E7E2", "#363531");
+ static readonly card: MobileColorPair = new MobileColorPair("#FFFFFF", "#252522");
+ static readonly accent: MobileColorPair = new MobileColorPair("#111111", "#5B5954");
+ static readonly fileLink: MobileColorPair = new MobileColorPair("#2563EB", "#60A5FA");
+ static readonly primaryAction: MobileColorPair = new MobileColorPair("#111111", "#454540");
+ static readonly contentOnAction: MobileColorPair = new MobileColorPair("#FFFFFF", "#FFFFFF");
+ static readonly connectHeroBg: MobileColorPair = new MobileColorPair("#E6EDFF", "#2B2B29");
+ static readonly connectHeroAccent: MobileColorPair = new MobileColorPair("#9DB4FF", "#4A4944");
+ static readonly connectHeroSecondary: MobileColorPair = new MobileColorPair("#C9C5FF", "#3C3B38");
+ static readonly connectHeroSurface: MobileColorPair = new MobileColorPair("#F8FAFF", "#252522");
+ static readonly connectScanAccent: MobileColorPair = new MobileColorPair("#FFD021", "#FFD021");
+ static readonly scrim: MobileColorPair = new MobileColorPair("#44000000", "#44000000");
+ static readonly shellScrim: MobileColorPair = new MobileColorPair("#24000000", "#24000000");
+ static readonly mediaBackground: MobileColorPair = new MobileColorPair("#FF000000", "#FF000000");
+ static readonly mediaScrim: MobileColorPair = new MobileColorPair("#B8000000", "#B8000000");
+ static readonly mediaControlBackground: MobileColorPair = new MobileColorPair("#8C000000", "#8C000000");
+ static readonly toastBackground: MobileColorPair = new MobileColorPair("#D1171717", "#D1171717");
+ static readonly shadowFaint: MobileColorPair = new MobileColorPair("#08000000", "#08000000");
+ static readonly shadowSubtle: MobileColorPair = new MobileColorPair("#12000000", "#12000000");
+ static readonly shadowMedium: MobileColorPair = new MobileColorPair("#18000000", "#18000000");
+ static readonly shadowStrong: MobileColorPair = new MobileColorPair("#24000000", "#24000000");
+ static readonly floatingBorder: MobileColorPair = new MobileColorPair("#18000000", "#18000000");
+ static readonly soft: MobileColorPair = new MobileColorPair("#F4F3F0", "#2D2C28");
+ static readonly floatingPanelBg: MobileColorPair = new MobileColorPair("#F7F7F5", "#1E1E1C");
+ static readonly statusSuccess: MobileColorPair = new MobileColorPair("#27C46A", "#3BD47B");
+ static readonly statusDanger: MobileColorPair = new MobileColorPair("#E04F4F", "#FF6B6B");
+ static readonly codeLineNumber: MobileColorPair = new MobileColorPair("#AAA69D", "#77756E");
+ static readonly codeKeyword: MobileColorPair = new MobileColorPair("#8F3F71", "#D99AC4");
+ static readonly codeString: MobileColorPair = new MobileColorPair("#477A4A", "#9BCB9D");
+ static readonly codeNumber: MobileColorPair = new MobileColorPair("#9A5B13", "#E3B36D");
+ static readonly codeComment: MobileColorPair = new MobileColorPair("#7A8078", "#96958D");
+ static readonly codeFunction: MobileColorPair = new MobileColorPair("#2C6693", "#8CBCE0");
+ static readonly codeType: MobileColorPair = new MobileColorPair("#865A20", "#D5B27F");
+ static readonly codeConstant: MobileColorPair = new MobileColorPair("#A04444", "#E79A9A");
+ static readonly codeProperty: MobileColorPair = new MobileColorPair("#466D78", "#9CC8D0");
+ static readonly codeTargetBg: MobileColorPair = new MobileColorPair("#FFF1BE", "#5A4E24");
+}
+
export class MobileTypographyToken {
readonly size: number;
readonly lineHeight: number;
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AccountProfilePanel.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AccountProfilePanel.ets
index 40b466d796..3af8301e0d 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AccountProfilePanel.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AccountProfilePanel.ets
@@ -2,7 +2,7 @@ import { MobileDesignGeometry, MobileDesignTypography } from '../../generated/Mo
import { RemoteI18n } from '../../i18n/RemoteI18n';
import { CloudAccountDevice } from '../../services/CloudAccountClient';
import { AccountDeviceSelectionPolicy } from '../policy/AccountDeviceSelectionPolicy';
-import { CARD, GREEN, INK, LINE, MUTED, PAGE_BG, RED, SOFT } from './Theme';
+import { CARD, STATUS_SUCCESS, INK, LINE, MUTED, PAGE_BG, STATUS_DANGER, SOFT } from './Theme';
import { DefaultAccountAvatar } from './DefaultAccountAvatar';
import { SheetCloseHeader } from './SheetCloseHeader';
@@ -91,7 +91,7 @@ export struct AccountProfilePanel {
RemoteI18n.t('remote.settings.accountNotSignedIn'))
.fontSize(MobileDesignTypography.bodySmall.size)
.fontWeight(FontWeight.Medium)
- .fontColor(this.isAccountAuthenticated() ? GREEN : MUTED)
+ .fontColor(this.isAccountAuthenticated() ? STATUS_SUCCESS : MUTED)
}
.width('100%')
.constraintSize({ minHeight: 72 })
@@ -161,7 +161,7 @@ export struct AccountProfilePanel {
Text(this.isAccountAuthenticated() ? RemoteI18n.t('remote.settings.accountSignedIn') :
RemoteI18n.t('remote.settings.accountNotSignedIn'))
.fontSize(MobileDesignTypography.bodyMedium.size)
- .fontColor(this.isAccountAuthenticated() ? GREEN : MUTED)
+ .fontColor(this.isAccountAuthenticated() ? STATUS_SUCCESS : MUTED)
}
.width('100%')
@@ -228,7 +228,7 @@ export struct AccountProfilePanel {
}
if (this.accountDevicesError.length > 0 && this.desktopDevices().length > 0) {
Text(this.accountDevicesError)
- .fontSize(MobileDesignTypography.bodySmall.size).lineHeight(MobileDesignTypography.bodySmall.lineHeight).fontColor(RED).width('100%')
+ .fontSize(MobileDesignTypography.bodySmall.size).lineHeight(MobileDesignTypography.bodySmall.lineHeight).fontColor(STATUS_DANGER).width('100%')
}
}
.width('100%')
@@ -256,7 +256,7 @@ export struct AccountProfilePanel {
.fontSize(MobileDesignTypography.titleSmall.size).fontWeight(FontWeight.Medium).fontColor(INK)
.maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })
Text(this.deviceStatus(device))
- .fontSize(MobileDesignTypography.bodySmall.size).fontColor(device.online ? GREEN : MUTED)
+ .fontSize(MobileDesignTypography.bodySmall.size).fontColor(device.online ? STATUS_SUCCESS : MUTED)
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
@@ -327,10 +327,10 @@ export struct AccountProfilePanel {
}
Row({ space: 14 }) {
SymbolGlyph($r('sys.symbol.arrow_right_and_square'))
- .fontSize(22).fontColor([RED]).width(24).height(24)
+ .fontSize(22).fontColor([STATUS_DANGER]).width(24).height(24)
Text(this.logoutBusy ? RemoteI18n.t('remote.settings.accountLoggingOut') :
RemoteI18n.t('remote.settings.accountLogout'))
- .fontSize(MobileDesignTypography.titleMedium.size).fontWeight(FontWeight.Medium).fontColor(RED)
+ .fontSize(MobileDesignTypography.titleMedium.size).fontWeight(FontWeight.Medium).fontColor(STATUS_DANGER)
}
.width('100%')
.constraintSize({ minHeight: 62 })
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AdaptiveSheetOptions.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AdaptiveSheetOptions.ets
index 7b1ae8250c..60251d4855 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AdaptiveSheetOptions.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AdaptiveSheetOptions.ets
@@ -1,4 +1,5 @@
import {
+import { SCRIM, TRANSPARENT } from './Theme';
SettingsPlacement,
SettingsPlacementMode
} from '../policy/SettingsPlacementPolicy';
@@ -13,8 +14,8 @@ export class AdaptiveSheetOptions {
return {
height: placement.height,
keyboardAvoidMode: SheetKeyboardAvoidMode.RESIZE_ONLY,
- backgroundColor: '#00000000',
- maskColor: '#44000000',
+ backgroundColor: TRANSPARENT,
+ maskColor: SCRIM,
showClose: false,
dragBar
};
@@ -25,8 +26,8 @@ export class AdaptiveSheetOptions {
width: placement.width,
keyboardAvoidMode: SheetKeyboardAvoidMode.RESIZE_ONLY,
preferType: SheetType.SIDE,
- backgroundColor: '#00000000',
- maskColor: '#44000000',
+ backgroundColor: TRANSPARENT,
+ maskColor: SCRIM,
showClose: false,
dragBar: false
};
@@ -37,8 +38,8 @@ export class AdaptiveSheetOptions {
width: placement.width,
keyboardAvoidMode: SheetKeyboardAvoidMode.RESIZE_ONLY,
preferType: SheetType.CENTER,
- backgroundColor: '#00000000',
- maskColor: '#44000000',
+ backgroundColor: TRANSPARENT,
+ maskColor: SCRIM,
showClose: false,
dragBar: false
};
@@ -47,8 +48,8 @@ export class AdaptiveSheetOptions {
return {
height: placement.height,
keyboardAvoidMode: SheetKeyboardAvoidMode.RESIZE_ONLY,
- backgroundColor: '#00000000',
- maskColor: '#44000000',
+ backgroundColor: TRANSPARENT,
+ maskColor: SCRIM,
showClose: false,
dragBar
};
@@ -56,8 +57,8 @@ export class AdaptiveSheetOptions {
return {
height: SheetSize.LARGE,
keyboardAvoidMode: SheetKeyboardAvoidMode.RESIZE_ONLY,
- backgroundColor: '#00000000',
- maskColor: '#44000000',
+ backgroundColor: TRANSPARENT,
+ maskColor: SCRIM,
showClose: false,
dragBar
};
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AppActionButton.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AppActionButton.ets
index 8a2960c9e9..a293be8a22 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AppActionButton.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AppActionButton.ets
@@ -1,5 +1,5 @@
import { MobileDesignGeometry, MobileDesignTypography } from '../../generated/MobileDesignTokens';
-import { CARD, INK, LINE, PRIMARY_ACTION, PRIMARY_ACTION_TEXT, RED, SOFT } from './Theme';
+import { CARD, CONTENT_ON_ACTION, INK, LINE, PRIMARY_ACTION, SOFT, STATUS_DANGER } from './Theme';
/** Visual intent for a product action. Layout may still choose its own width and height. */
export enum AppActionStyle {
@@ -24,7 +24,7 @@ export struct AppActionButton {
.height(this.actionHeight)
.fontSize(MobileDesignTypography.labelLarge.size)
.fontWeight(FontWeight.Medium)
- .fontColor(this.isFilled() ? PRIMARY_ACTION_TEXT : INK)
+ .fontColor(this.isFilled() ? CONTENT_ON_ACTION : INK)
.backgroundColor(this.actionBackgroundColor())
.border({ width: this.style === AppActionStyle.Secondary ? 1 : 0, color: LINE })
.borderRadius(this.actionHeight / 2)
@@ -41,7 +41,7 @@ export struct AppActionButton {
private actionBackgroundColor(): ResourceColor {
if (this.style === AppActionStyle.Primary) return PRIMARY_ACTION;
- if (this.style === AppActionStyle.Destructive) return RED;
+ if (this.style === AppActionStyle.Destructive) return STATUS_DANGER;
if (this.style === AppActionStyle.Quiet) return SOFT;
return CARD;
}
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AppShell.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AppShell.ets
index 8d6be34bea..d0ffa737ef 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AppShell.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AppShell.ets
@@ -7,7 +7,11 @@ import {
SettingsSheetKind
} from '../policy/SettingsPlacementPolicy';
import { AdaptiveSheetOptions } from './AdaptiveSheetOptions';
-import { PAGE_BG } from './Theme';
+import {
+ PAGE_BG,
+ SHELL_SCRIM,
+ TRANSPARENT,
+} from './Theme';
const WIDE_SHEET_RADIUS: number = 30;
@@ -77,7 +81,7 @@ export struct AppShell {
.clip(true)
.shadow({
radius: this.shellState.showSidebar ? 34 : 0,
- color: this.shellState.showSidebar ? '#24000000' : '#00000000',
+ color: this.shellState.showSidebar ? SHELL_SCRIM : TRANSPARENT,
offsetX: this.shellState.showSidebar ? -10 : 0
})
.blur(this.shellState.showSidebar ? 1.1 : 0)
@@ -112,7 +116,7 @@ export struct AppShell {
.clip(this.usesWideSheetChrome(this.settingsPlacement))
.shadow({
radius: this.usesWideSheetChrome(this.settingsPlacement) ? 30 : 0,
- color: this.usesWideSheetChrome(this.settingsPlacement) ? '#22000000' : '#00000000',
+ color: this.usesWideSheetChrome(this.settingsPlacement) ? SHELL_SCRIM : TRANSPARENT,
offsetY: this.usesWideSheetChrome(this.settingsPlacement) ? 12 : 0
})
}
@@ -128,7 +132,7 @@ export struct AppShell {
.clip(this.usesWideSheetChrome(this.connectPlacement))
.shadow({
radius: this.usesWideSheetChrome(this.connectPlacement) ? 30 : 0,
- color: this.usesWideSheetChrome(this.connectPlacement) ? '#22000000' : '#00000000',
+ color: this.usesWideSheetChrome(this.connectPlacement) ? SHELL_SCRIM : TRANSPARENT,
offsetY: this.usesWideSheetChrome(this.connectPlacement) ? 12 : 0
})
}
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AppSidebar.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AppSidebar.ets
index ca626ef7c1..495d8797c2 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AppSidebar.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/AppSidebar.ets
@@ -1,7 +1,7 @@
import { MobileDesignGeometry, MobileDesignTypography } from '../../generated/MobileDesignTokens';
import { RemoteSession } from '../../model/RemoteModels';
import { RemoteI18n } from '../../i18n/RemoteI18n';
-import { CARD, INK, LINE, MUTED, PAGE_BG, PAGE_BG_FADE, SOFT, SUBTLE } from './Theme';
+import { CARD, INK, LINE, MUTED, PAGE_BG, PAGE_BG_FADE, SCRIM, SOFT, SUBTLE, TRANSPARENT } from './Theme';
import { SidebarToggleButton } from './SidebarToggleButton';
import { SessionActionPresentation, SessionActionSurface } from './SessionActionSurface';
import { AdaptiveSheetOptions } from './AdaptiveSheetOptions';
@@ -215,7 +215,7 @@ export struct AppSidebar {
.width(MobileDesignGeometry.controlTouchSize)
.height(MobileDesignGeometry.controlTouchSize)
.padding(0)
- .backgroundColor('#00000000')
+ .backgroundColor(TRANSPARENT)
.borderRadius(12)
.stateEffect(true)
.accessibilityText(RemoteI18n.t('remote.actions'))
@@ -230,7 +230,7 @@ export struct AppSidebar {
.width(MobileDesignGeometry.controlTouchSize)
.height(MobileDesignGeometry.controlTouchSize)
.padding(0)
- .backgroundColor('#00000000')
+ .backgroundColor(TRANSPARENT)
.borderRadius(12)
.stateEffect(true)
.accessibilityText(RemoteI18n.t('common.search'))
@@ -338,7 +338,7 @@ export struct AppSidebar {
.width(48)
.height(48)
.padding(0)
- .backgroundColor('#00000000')
+ .backgroundColor(TRANSPARENT)
.borderRadius(12)
.stateEffect(true)
.onClick(() => {
@@ -440,7 +440,7 @@ export struct AppSidebar {
.height(46)
.padding({ left: 12, right: 68 })
.margin({ top: 8 })
- .backgroundColor(this.archivedSessionsExpanded ? SOFT : '#00000000')
+ .backgroundColor(this.archivedSessionsExpanded ? SOFT : TRANSPARENT)
.borderRadius(10)
.onClick(() => {
this.archivedSessionsExpanded = !this.archivedSessionsExpanded;
@@ -460,14 +460,14 @@ export struct AppSidebar {
}
.width('100%').height(44)
.padding({ left: 12, right: 4 })
- .backgroundColor(this.selectedSessionId === session.id ? SOFT : '#00000000')
+ .backgroundColor(this.selectedSessionId === session.id ? SOFT : TRANSPARENT)
.borderRadius(10)
.onClick(() => this.openSession(session))
.gesture(LongPressGesture({ repeat: false }).onAction(() => this.openSessionActions(session)))
.bindPopup(this.showCollapseButton && this.activeActionSessionId === session.id, {
builder: () => { this.SessionActionPopover() },
placement: Placement.Right,
- popupColor: '#00000000',
+ popupColor: TRANSPARENT,
enableArrow: false,
autoCancel: true,
mask: false,
@@ -496,7 +496,7 @@ export struct AppSidebar {
.height(44)
.padding({ left: 12, right: 4 })
.backgroundColor(this.selectedSessionId === item.id || this.activeActionSessionId === item.id ?
- SOFT : '#00000000')
+ SOFT : TRANSPARENT)
.borderRadius(10)
.onClick(() => {
this.openSession(item);
@@ -505,7 +505,7 @@ export struct AppSidebar {
.bindPopup(this.showCollapseButton && this.activeActionSessionId === item.id, {
builder: () => { this.SessionActionPopover() },
placement: Placement.Right,
- popupColor: '#00000000',
+ popupColor: TRANSPARENT,
enableArrow: false,
autoCancel: true,
mask: false,
@@ -711,8 +711,8 @@ export struct AppSidebar {
private sessionActionSheetOptions(): SheetOptions {
return {
height: this.actionSessionIsGeneralChat() ? 380 : 300,
- backgroundColor: '#00000000',
- maskColor: '#44000000',
+ backgroundColor: TRANSPARENT,
+ maskColor: SCRIM,
showClose: false,
dragBar: false
};
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/BitFunAccountLoginPage.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/BitFunAccountLoginPage.ets
index 88c24eb110..0c6adf875b 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/BitFunAccountLoginPage.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/BitFunAccountLoginPage.ets
@@ -7,7 +7,7 @@ import {
LINE,
MUTED,
PAGE_BG_FADE,
- RED,
+ STATUS_DANGER,
SUBTLE
} from './Theme';
import { SheetActionFooter } from './SheetActionFooter';
@@ -94,7 +94,7 @@ export struct BitFunAccountLoginPage {
Text(this.errorText)
.fontSize(MobileDesignTypography.bodySmall.size)
.lineHeight(MobileDesignTypography.bodySmall.lineHeight)
- .fontColor(RED)
+ .fontColor(STATUS_DANGER)
.width('100%')
.margin({ top: 12, left: 4, right: 4 })
}
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ChatMessageBubble.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ChatMessageBubble.ets
index de5ee1c27f..bb77bee144 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ChatMessageBubble.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ChatMessageBubble.ets
@@ -6,7 +6,7 @@ import { ChatMessageStructurePolicy, StructuredRenderGroup } from '../policy/Cha
import { AssistantProcessLayoutPolicy } from '../policy/AssistantProcessLayoutPolicy';
import { ConversationMessageRenderPolicy } from '../policy/ConversationMessageRenderPolicy';
import { ThinkingPresentationPolicy } from '../policy/ThinkingPresentationPolicy';
-import { ACCENT, INK, LINE, RED } from './Theme';
+import { ACCENT, INK, LINE, STATUS_DANGER } from './Theme';
import { MessageBodyMarkdown, MessageFileCards, MessageImageGallery, MessageMarkdown } from './ChatMessageContent';
import { ChatMessageRetryAction, ChatTypingDots, ChatUserMessageBubble } from './ChatMessageChrome';
import { SubagentTaskCard } from './SubagentTaskCard';
@@ -121,7 +121,7 @@ export struct ChatMessageBubble {
Text(RemoteI18n.t('chat.responseFailed'))
.fontSize(MobileDesignTypography.labelSmall.size)
.fontWeight(FontWeight.Medium)
- .fontColor(RED)
+ .fontColor(STATUS_DANGER)
Text(errorText.trim())
.fontSize(MobileDesignTypography.bodySmall.size)
.lineHeight(MobileDesignTypography.bodySmall.lineHeight)
@@ -138,7 +138,7 @@ export struct ChatMessageBubble {
}
.width('100%')
.padding({ left: 12, top: 2, bottom: 2 })
- .border({ width: { left: 2 }, color: RED })
+ .border({ width: { left: 2 }, color: STATUS_DANGER })
.alignItems(HorizontalAlign.Start)
}
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ChatMessageChrome.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ChatMessageChrome.ets
index 1c3c357d66..d38e42b2d1 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ChatMessageChrome.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ChatMessageChrome.ets
@@ -2,7 +2,7 @@ import { MobileDesignGeometry, MobileDesignTypography } from '../../generated/Mo
import { RemoteI18n } from '../../i18n/RemoteI18n';
import { ConversationUiMessage } from '../state/ConversationUiModels';
import { MessageImageGallery } from './ChatMessageContent';
-import { ACCENT, INK, MUTED, PRIMARY_ACTION_TEXT, RED, SOFT } from './Theme';
+import { ACCENT, INK, MUTED, CONTENT_ON_ACTION, STATUS_DANGER, SOFT } from './Theme';
@ComponentV2
export struct ChatTypingDots {
@@ -49,10 +49,10 @@ export struct ChatMessageRetryAction {
Row({ space: 8 }) {
Text(this.assistant ? RemoteI18n.t('generalChat.replyInterrupted') : RemoteI18n.t('chat.sendFailed'))
.fontSize(MobileDesignTypography.labelSmall.size)
- .fontColor(RED)
+ .fontColor(STATUS_DANGER)
Text(RemoteI18n.t('common.retry'))
.fontSize(MobileDesignTypography.labelSmall.size)
- .fontColor(PRIMARY_ACTION_TEXT)
+ .fontColor(CONTENT_ON_ACTION)
.height(28)
.padding({ left: 10, right: 10 })
.backgroundColor(ACCENT)
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ChatTimeline.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ChatTimeline.ets
index 4db8c96ac5..eb8104bcfa 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ChatTimeline.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ChatTimeline.ets
@@ -13,7 +13,14 @@ import {
ObservableChatTimelineItem
} from '../../model/ChatTimelineModels';
import { ChatSurface } from '../state/ChatSurface';
-import { CARD, INK, LINE, MUTED, RED } from './Theme';
+import {
+ CARD,
+ INK,
+ LINE,
+ MUTED,
+ SHADOW_SUBTLE,
+ STATUS_DANGER,
+} from './Theme';
import { ChatMessageBubble, ChatUserMessageRow } from './ChatMessageBubble';
import { RemoteLogger } from '../../services/RemoteLogger';
@@ -324,7 +331,7 @@ export struct ChatTimeline {
.height(42)
.backgroundColor(CARD)
.borderRadius(21)
- .shadow({ radius: 14, color: '#14000000', offsetY: 5 })
+ .shadow({ radius: 14, color: SHADOW_SUBTLE, offsetY: 5 })
.margin({ bottom: 4 })
.onClick(() => {
this.stickToBottom = true;
@@ -346,7 +353,7 @@ export struct ChatTimeline {
.width(38)
.height(38)
.fontSize(MobileDesignTypography.headlineSmall.size)
- .fontColor(this.connectionState === 'failed' ? RED : MUTED)
+ .fontColor(this.connectionState === 'failed' ? STATUS_DANGER : MUTED)
.textAlign(TextAlign.Center)
.backgroundColor(CARD)
.borderRadius(14)
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/CompactMenuButton.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/CompactMenuButton.ets
index 2f228cf558..46507219ca 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/CompactMenuButton.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/CompactMenuButton.ets
@@ -1,5 +1,6 @@
import { RemoteI18n } from '../../i18n/RemoteI18n';
import { TemplateIcon } from './TemplateIcon';
+import { TRANSPARENT } from './Theme';
@ComponentV2
export struct CompactMenuButton {
@@ -17,7 +18,7 @@ export struct CompactMenuButton {
.width(this.controlSize)
.height(this.controlSize)
.padding(0)
- .backgroundColor('#00000000')
+ .backgroundColor(TRANSPARENT)
.borderRadius(12)
.stateEffect(true)
.accessibilityText(RemoteI18n.t('sidebar.more'))
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ComposerBar.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ComposerBar.ets
index b4d96a088c..d80eb24abe 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ComposerBar.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ComposerBar.ets
@@ -11,15 +11,21 @@ import {
import { ConversationModelPresentationPolicy } from '../policy/ConversationModelPresentationPolicy';
import {
CARD,
+ CONTENT_ON_ACTION,
FLOATING_PANEL_BG,
- GREEN,
INK,
LINE,
+ MEDIA_SCRIM,
MUTED,
PRIMARY_ACTION,
- PRIMARY_ACTION_TEXT,
- RED,
- SOFT
+ SCRIM,
+ SHADOW_FAINT,
+ SHADOW_MEDIUM,
+ SHADOW_SUBTLE,
+ SOFT,
+ STATUS_DANGER,
+ STATUS_SUCCESS,
+ TRANSPARENT
} from './Theme';
export enum ComposerPresentation {
@@ -97,7 +103,7 @@ export struct ComposerBar {
top: 8,
bottom: this.presentation === ComposerPresentation.Floating ? 16 : 12
})
- .backgroundColor('#00000000')
+ .backgroundColor(TRANSPARENT)
.bindSheet($$this.showModelSelectorSheet, this.ModelSelector(true), this.modelSelectorSheetOptions())
}
@@ -165,7 +171,7 @@ export struct ComposerBar {
.borderRadius(this.composerRadius())
.shadow({
radius: this.presentation === ComposerPresentation.Floating ? 14 : 8,
- color: this.presentation === ComposerPresentation.Floating ? '#10000000' : '#08000000',
+ color: this.presentation === ComposerPresentation.Floating ? SHADOW_SUBTLE : SHADOW_FAINT,
offsetY: this.presentation === ComposerPresentation.Floating ? 4 : 2
})
.animation({ duration: MobileDesignMotion.structure, curve: Curve.EaseOut })
@@ -194,14 +200,14 @@ export struct ComposerBar {
.height(32)
.constraintSize({ maxWidth: 220 })
.padding({ left: 4, right: 4 })
- .backgroundColor('#00000000')
+ .backgroundColor(TRANSPARENT)
.accessibilityText(`${RemoteI18n.t('chat.selectModel')} · ${this.displaySelectedModel()}`)
.bindPopup(this.showModelSelectorPopover, {
builder: () => {
this.ModelSelector(false)
},
placement: Placement.Top,
- popupColor: '#00000000',
+ popupColor: TRANSPARENT,
enableArrow: false,
autoCancel: true,
mask: false,
@@ -264,8 +270,8 @@ export struct ComposerBar {
.backgroundColor(asSheet ? CARD : FLOATING_PANEL_BG)
.borderRadius(asSheet ? { topLeft: 20, topRight: 20 } :
MobileDesignGeometry.composerModelSelectorRadius)
- .border({ width: asSheet ? 0 : 1, color: asSheet ? '#00000000' : LINE })
- .shadow({ radius: asSheet ? 0 : 18, color: asSheet ? '#00000000' : '#18000000', offsetY: 7 })
+ .border({ width: asSheet ? 0 : 1, color: asSheet ? TRANSPARENT : LINE })
+ .shadow({ radius: asSheet ? 0 : 18, color: asSheet ? TRANSPARENT : SHADOW_MEDIUM, offsetY: 7 })
}
@Builder
@@ -300,7 +306,7 @@ export struct ComposerBar {
.width('100%')
.height(MobileDesignGeometry.composerModelSelectorRowHeight)
.padding({ left: 10, right: 10 })
- .backgroundColor(this.isSelectedModel(model) ? SOFT : '#00000000')
+ .backgroundColor(this.isSelectedModel(model) ? SOFT : TRANSPARENT)
.borderRadius(MobileDesignGeometry.composerModelSelectorRowRadius)
.onClick(() => {
this.closeModelSelector();
@@ -338,8 +344,8 @@ export struct ComposerBar {
.height(this.isComposerExpanded() ? COMPOSER_EXPANDED_INPUT_HEIGHT : COMPOSER_INPUT_HEIGHT)
.fontSize(MobileDesignTypography.bodyLarge.size)
.fontColor(INK)
- .placeholderColor(this.isVoiceListening ? GREEN : MUTED)
- .backgroundColor('#00000000')
+ .placeholderColor(this.isVoiceListening ? STATUS_SUCCESS : MUTED)
+ .backgroundColor(TRANSPARENT)
.borderRadius(20)
.padding({
left: this.isVoiceListening ? 0 : 4,
@@ -369,9 +375,9 @@ export struct ComposerBar {
.height(this.isComposerExpanded() ? COMPOSER_EXPANDED_INPUT_HEIGHT : COMPOSER_INPUT_HEIGHT)
.alignItems(VerticalAlign.Center)
.padding({ left: this.isVoiceListening ? 12 : 0, right: 0 })
- .backgroundColor(this.isVoiceListening ? SOFT : '#00000000')
+ .backgroundColor(this.isVoiceListening ? SOFT : TRANSPARENT)
.borderRadius(20)
- .border({ width: this.isVoiceListening ? 1 : 0, color: this.isVoiceListening ? GREEN : '#00000000' })
+ .border({ width: this.isVoiceListening ? 1 : 0, color: this.isVoiceListening ? STATUS_SUCCESS : TRANSPARENT })
}
@Builder
@@ -450,22 +456,22 @@ export struct ComposerBar {
Text('')
.width(3)
.height(10)
- .backgroundColor(GREEN)
+ .backgroundColor(STATUS_SUCCESS)
.borderRadius(2)
Text('')
.width(3)
.height(18)
- .backgroundColor(GREEN)
+ .backgroundColor(STATUS_SUCCESS)
.borderRadius(2)
Text('')
.width(3)
.height(24)
- .backgroundColor(GREEN)
+ .backgroundColor(STATUS_SUCCESS)
.borderRadius(2)
Text('')
.width(3)
.height(14)
- .backgroundColor(GREEN)
+ .backgroundColor(STATUS_SUCCESS)
.borderRadius(2)
}
.width(22)
@@ -508,7 +514,7 @@ export struct ComposerBar {
.fontSize(MobileDesignTypography.bodyLarge.size)
.fontColor(CARD)
.textAlign(TextAlign.Center)
- .backgroundColor('#AA222222')
+ .backgroundColor(MEDIA_SCRIM)
.borderRadius(16)
.margin({ top: 0, right: 0 })
.accessibilityText(RemoteI18n.t('chat.removeImage'))
@@ -659,8 +665,8 @@ export struct ComposerBar {
private modelSelectorSheetOptions(): SheetOptions {
return {
height: Math.min(480, 86 + this.modelListHeight()),
- backgroundColor: '#00000000',
- maskColor: '#44000000',
+ backgroundColor: TRANSPARENT,
+ maskColor: SCRIM,
showClose: false,
dragBar: true
};
@@ -684,14 +690,14 @@ export struct ComposerBar {
action === ComposerPrimaryAction.Idle) {
return SOFT;
}
- return this.isVoiceListening ? GREEN : RED;
+ return this.isVoiceListening ? STATUS_SUCCESS : STATUS_DANGER;
}
private primaryActionForegroundColor(): ResourceColor {
const action = this.primaryAction();
if (action === ComposerPrimaryAction.Send || action === ComposerPrimaryAction.Voice ||
action === ComposerPrimaryAction.Stop) {
- return PRIMARY_ACTION_TEXT;
+ return CONTENT_ON_ACTION;
}
return MUTED;
}
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConnectAccountDevicePage.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConnectAccountDevicePage.ets
index ca70ba69b7..6bc92654dc 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConnectAccountDevicePage.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConnectAccountDevicePage.ets
@@ -1,7 +1,7 @@
import { MobileDesignTypography } from '../../generated/MobileDesignTokens';
import { RemoteI18n } from '../../i18n/RemoteI18n';
import { CloudAccountDevice } from '../../services/CloudAccountClient';
-import { ACCENT, CARD, GREEN, INK, LINE, MUTED, PAGE_BG, RED, SOFT } from './Theme';
+import { ACCENT, CARD, STATUS_SUCCESS, INK, LINE, MUTED, PAGE_BG, STATUS_DANGER, SOFT } from './Theme';
import { AccountDeviceSelectionPolicy } from '../policy/AccountDeviceSelectionPolicy';
import { NavigationBackButton } from './NavigationBackButton';
@@ -74,7 +74,7 @@ export struct ConnectAccountDevicePage {
(this.accountDevicesError.length > 0 ? RemoteI18n.t('common.retry') : RemoteI18n.t('common.refresh')))
.fontSize(MobileDesignTypography.bodyMedium.size)
.fontColor(this.accountDevicesBusy ? MUTED :
- (this.accountDevicesError.length > 0 ? RED : ACCENT))
+ (this.accountDevicesError.length > 0 ? STATUS_DANGER : ACCENT))
.onClick(async () => { await this.refreshAccountDevices(); })
}
.width('100%').height(38)
@@ -148,7 +148,7 @@ export struct ConnectAccountDevicePage {
.fontSize(MobileDesignTypography.titleSmall.size).fontWeight(FontWeight.Medium).fontColor(INK)
.maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })
Text(this.accountDeviceStatus(device))
- .fontSize(MobileDesignTypography.bodySmall.size).fontColor(device.online ? GREEN : MUTED)
+ .fontSize(MobileDesignTypography.bodySmall.size).fontColor(device.online ? STATUS_SUCCESS : MUTED)
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConnectManualPairingOverlay.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConnectManualPairingOverlay.ets
index 49582df9e6..6b24e251eb 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConnectManualPairingOverlay.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConnectManualPairingOverlay.ets
@@ -1,6 +1,6 @@
import { MobileDesignTypography } from '../../generated/MobileDesignTokens';
import { RemoteI18n } from '../../i18n/RemoteI18n';
-import { CARD, INK, LINE, MODAL_SCRIM, MUTED, SOFT } from './Theme';
+import { CARD, INK, LINE, MUTED, SCRIM, SOFT } from './Theme';
import { AppActionButton, AppActionStyle } from './AppActionButton';
@ComponentV2
@@ -21,7 +21,7 @@ export struct ConnectManualPairingOverlay {
Text('')
.width('100%')
.height('100%')
- .backgroundColor(MODAL_SCRIM)
+ .backgroundColor(SCRIM)
.onClick(this.onCancel)
Column({ space: 20 }) {
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConnectView.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConnectView.ets
index 72eecd12d4..dd1399dfef 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConnectView.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConnectView.ets
@@ -21,8 +21,8 @@ import {
import { DetectedUrlAction } from '../../services/ConnectScanDecisionPolicy';
import { InlineQrScanner } from './platform/InlineQrScanner';
import { CARD, CONNECT_HERO_ACCENT, CONNECT_HERO_BG, CONNECT_HERO_SECONDARY,
- CONNECT_HERO_SURFACE, CONNECT_SCAN_ACCENT, GREEN, INK, LINE, MUTED, PAGE_BG, RED, SOFT,
- SUBTLE } from './Theme';
+ CONNECT_HERO_SURFACE, CONNECT_SCAN_ACCENT, INK, LINE, MUTED, PAGE_BG, SHADOW_MEDIUM, SOFT,
+ STATUS_DANGER, STATUS_SUCCESS, SUBTLE } from './Theme';
const SCAN_FRAME_SIZE: number = 248;
const SCAN_CORNER_SIZE: number = 56;
@@ -342,7 +342,7 @@ export struct ConnectView {
Text('')
.width(SCAN_FRAME_SIZE)
.height(SCAN_FRAME_SIZE)
- .backgroundColor('#18000000')
+ .backgroundColor(SHADOW_MEDIUM)
.borderRadius(28)
this.ScanCorner(SCAN_CORNER_INSET, SCAN_CORNER_INSET, true, true)
this.ScanCorner(
@@ -447,10 +447,10 @@ export struct ConnectView {
private statusDotColor(): ResourceColor {
if (this.isConnected) {
- return GREEN;
+ return STATUS_SUCCESS;
}
if (this.isConnectError()) {
- return RED;
+ return STATUS_DANGER;
}
if (this.isBusy || this.connectionState === 'parsing' || this.connectionState === 'pairing' || this.connectionState === 'reconnecting') {
return INK;
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConversationHeader.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConversationHeader.ets
index 80ea620a9b..4adbab11a0 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConversationHeader.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConversationHeader.ets
@@ -1,6 +1,16 @@
import { RemoteI18n } from '../../i18n/RemoteI18n';
import { MobileDesignGeometry, MobileDesignTypography } from '../../generated/MobileDesignTokens';
-import { ACCENT, CARD, INK, LINE, MUTED, PAGE_BG, PRIMARY_ACTION_TEXT, SOFT } from './Theme';
+import {
+ ACCENT,
+ CARD,
+ CONTENT_ON_ACTION,
+ INK,
+ LINE,
+ MUTED,
+ PAGE_BG,
+ SOFT,
+ TRANSPARENT,
+} from './Theme';
import { CompactMenuButton } from './CompactMenuButton';
import { NavigationBackButton } from './NavigationBackButton';
import { TemplateIcon } from './TemplateIcon';
@@ -134,7 +144,7 @@ export struct ConversationHeader {
.width(MobileDesignGeometry.controlTouchSize)
.height(MobileDesignGeometry.controlTouchSize)
.padding(0)
- .backgroundColor('#00000000')
+ .backgroundColor(TRANSPARENT)
.borderRadius(12)
.stateEffect(true)
.accessibilityText(RemoteI18n.t('sidebar.more'))
@@ -143,7 +153,7 @@ export struct ConversationHeader {
this.actionsMenu();
},
placement: Placement.BottomRight,
- popupColor: '#00000000',
+ popupColor: TRANSPARENT,
enableArrow: false,
autoCancel: true,
mask: false,
@@ -182,7 +192,7 @@ export struct ConversationHeader {
.width(52)
.height(42)
.fontSize(MobileDesignTypography.bodySmall.size)
- .fontColor(PRIMARY_ACTION_TEXT)
+ .fontColor(CONTENT_ON_ACTION)
.textAlign(TextAlign.Center)
.backgroundColor(this.renameTitle.trim().length > 0 ? ACCENT : SOFT)
.borderRadius(14)
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConversationView.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConversationView.ets
index b170fe7c81..398c827e52 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConversationView.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConversationView.ets
@@ -24,7 +24,17 @@ import {
import { ComposerBar, ComposerPresentation } from './ComposerBar';
import { ConversationHeader } from './ConversationHeader';
import { ConversationHeaderPolicy, ConversationHeaderPresentation } from '../policy/ConversationHeaderPolicy';
-import { FLOATING_PANEL_BG, GREEN, INK, LINE, MUTED, PAGE_BG, RED, SOFT } from './Theme';
+import {
+ FLOATING_PANEL_BG,
+ INK,
+ LINE,
+ MUTED,
+ PAGE_BG,
+ SOFT,
+ STATUS_DANGER,
+ STATUS_SUCCESS,
+ TRANSPARENT,
+} from './Theme';
@ComponentV2
export struct ConversationView {
@@ -334,7 +344,7 @@ export struct ConversationView {
.width('100%').height(48)
.padding({ left: 8, right: 8 })
.borderRadius(10)
- .backgroundColor(selected ? SOFT : '#00000000')
+ .backgroundColor(selected ? SOFT : TRANSPARENT)
.onClick(() => {
action()
this.showHeaderActions = false
@@ -375,7 +385,7 @@ export struct ConversationView {
private statusColor(): ResourceColor {
if (this.canStop && this.connectionState === 'connected') {
- return GREEN;
+ return STATUS_SUCCESS;
}
return this.connectionColor();
}
@@ -440,10 +450,10 @@ export struct ConversationView {
private connectionColor(): ResourceColor {
const tone = ConnectionStatusPresenter.tone(this.connectionState);
if (tone === 'ok') {
- return GREEN;
+ return STATUS_SUCCESS;
}
if (tone === 'error') {
- return RED;
+ return STATUS_DANGER;
}
return MUTED;
}
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConversationViewSettings.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConversationViewSettings.ets
index 3eba8e2968..aa60b040cd 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConversationViewSettings.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ConversationViewSettings.ets
@@ -3,7 +3,14 @@ import { RemoteI18n } from '../../i18n/RemoteI18n';
import { RecentWorkspaceEntry, RemoteSession } from '../../model/RemoteModels';
import { RemoteLogger } from '../../services/RemoteLogger';
import { ConversationSessionFilterPolicy } from '../policy/ConversationSessionFilterPolicy';
-import { CARD, INK, LINE, MUTED, PAGE_BG } from './Theme';
+import {
+ CARD,
+ INK,
+ LINE,
+ MUTED,
+ PAGE_BG,
+ TRANSPARENT,
+} from './Theme';
@ComponentV2
struct WorkspaceFilterSection {
@@ -31,7 +38,7 @@ struct WorkspaceFilterSection {
.width('100%')
.height(46)
.padding({ left: 10, right: 10 })
- .backgroundColor(this.currentValue.length === 0 ? CARD : '#00000000')
+ .backgroundColor(this.currentValue.length === 0 ? CARD : TRANSPARENT)
.border({ width: { bottom: 1 }, color: LINE })
.onClick(() => this.selectWorkspace(''))
ForEach(this.options, (item: RecentWorkspaceEntry) => {
@@ -52,7 +59,7 @@ struct WorkspaceFilterSection {
.height(46)
.padding({ left: 10, right: 10 })
.backgroundColor(ConversationSessionFilterPolicy.workspacePathsEqual(this.currentValue, item.path)
- ? CARD : '#00000000')
+ ? CARD : TRANSPARENT)
.border({ width: { bottom: 1 }, color: LINE })
.onClick(() => this.selectWorkspace(item.path))
}, (item: RecentWorkspaceEntry): string => item.path)
@@ -216,7 +223,7 @@ export struct ConversationViewSettings {
.width('100%')
.height(48)
.padding({ left: 10, right: 10 })
- .backgroundColor(this.selectedSortMode === mode ? CARD : '#00000000')
+ .backgroundColor(this.selectedSortMode === mode ? CARD : TRANSPARENT)
.opacity(_revision % 2 === 0 ? 1 : 0.999)
.border({ width: { bottom: 1 }, color: LINE })
.onClick(() => this.selectSortMode(mode))
@@ -240,7 +247,7 @@ export struct ConversationViewSettings {
.width('100%')
.height(46)
.padding({ left: 10, right: 10 })
- .backgroundColor(selected ? CARD : '#00000000')
+ .backgroundColor(selected ? CARD : TRANSPARENT)
.opacity(_revision % 2 === 0 ? 1 : 0.999)
.border({ width: { bottom: 1 }, color: LINE })
.onClick(() => action(value))
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/FilePreviewSurface.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/FilePreviewSurface.ets
index 41a1e4dec4..587b671071 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/FilePreviewSurface.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/FilePreviewSurface.ets
@@ -30,7 +30,8 @@ import {
LINE,
MUTED,
PAGE_BG,
- SOFT
+ SOFT,
+ TRANSPARENT,
} from './Theme';
@ComponentV2
@@ -330,7 +331,7 @@ export struct FilePreviewSurface {
Span(token.text)
.fontColor(this.syntaxTokenColor(token.kind))
.textBackgroundStyle({
- color: this.isTargetLine(token.lineNumber) ? CODE_TARGET_BG : '#00000000'
+ color: this.isTargetLine(token.lineNumber) ? CODE_TARGET_BG : TRANSPARENT
})
}, (token: CodeSyntaxToken) => token.id)
}
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ModelServiceSettingsPanel.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ModelServiceSettingsPanel.ets
index 7bf6f871c1..11d561d5a9 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ModelServiceSettingsPanel.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ModelServiceSettingsPanel.ets
@@ -5,7 +5,7 @@ import { RemoteModelCatalog, RemoteModelConfig } from '../../model/RemoteModels'
import { GENERAL_CHAT_LOCAL_MODEL_ID } from '../../services/general-chat/GeneralChatConfigStore';
import { ModelServiceSettingsPolicy } from '../policy/ModelServiceSettingsPolicy';
import { SettingsSheetState } from '../state/SettingsSheetState';
-import { CARD, GREEN, INK, LINE, MUTED, RED, SOFT, SUBTLE } from './Theme';
+import { CARD, INK, LINE, MUTED, SOFT, STATUS_DANGER, STATUS_SUCCESS, SUBTLE, TRANSPARENT } from './Theme';
import { SheetCloseHeader } from './SheetCloseHeader';
import { AppActionButton, AppActionStyle } from './AppActionButton';
@@ -216,7 +216,7 @@ export struct ModelServiceSettingsPanel {
.width('100%')
.height(ModelServiceSettingsPolicy.ACCOUNT_MODEL_ROW_HEIGHT)
.padding({ left: 10, right: 10 })
- .backgroundColor(this.isSelectedModel(model) ? SOFT : '#00000000')
+ .backgroundColor(this.isSelectedModel(model) ? SOFT : TRANSPARENT)
.borderRadius(9)
.onClick(() => {
this.onSelectModel(model.id);
@@ -275,7 +275,7 @@ export struct ModelServiceSettingsPanel {
Text(this.feedbackText)
.fontSize(MobileDesignTypography.bodySmall.size)
.lineHeight(MobileDesignTypography.bodySmall.lineHeight)
- .fontColor(this.feedbackIsError ? RED : GREEN)
+ .fontColor(this.feedbackIsError ? STATUS_DANGER : STATUS_SUCCESS)
.width('100%')
}
}
@@ -504,7 +504,7 @@ export struct ModelServiceSettingsPanel {
RemoteI18n.t('settings.modelService.clearKey'))
.fontSize(MobileDesignTypography.bodySmall.size)
.fontWeight(FontWeight.Medium)
- .fontColor(this.sheetState.draftClearApiKey ? INK : RED)
+ .fontColor(this.sheetState.draftClearApiKey ? INK : STATUS_DANGER)
.width('100%')
.onClick(() => {
this.sheetState.draftClearApiKey = !this.sheetState.draftClearApiKey;
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/NavigationBackButton.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/NavigationBackButton.ets
index 4b57ca9a08..fa1b16d2dc 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/NavigationBackButton.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/NavigationBackButton.ets
@@ -1,5 +1,6 @@
import { RemoteI18n } from '../../i18n/RemoteI18n';
import { TemplateIcon } from './TemplateIcon';
+import { TRANSPARENT } from './Theme';
/** App-wide floating page return affordance. */
@ComponentV2
@@ -19,7 +20,7 @@ export struct NavigationBackButton {
.width(this.controlSize)
.height(this.controlSize)
.padding(0)
- .backgroundColor('#00000000')
+ .backgroundColor(TRANSPARENT)
.borderRadius(12)
.stateEffect(true)
.opacity(this.isEnabled ? 1 : 0.4)
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/RemoteControlSettingsSheet.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/RemoteControlSettingsSheet.ets
index d054aa7ae1..34fa7b687e 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/RemoteControlSettingsSheet.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/RemoteControlSettingsSheet.ets
@@ -1,6 +1,6 @@
import { MobileDesignTypography } from '../../generated/MobileDesignTokens';
import { RemoteI18n } from '../../i18n/RemoteI18n';
-import { CARD, INK, LINE, MUTED, PAGE_BG, RED, SOFT } from './Theme';
+import { CARD, INK, LINE, MUTED, PAGE_BG, SOFT, STATUS_DANGER } from './Theme';
import { CloudAccountDevice } from '../../services/CloudAccountClient';
import { RemotePermissionMode } from '../../model/RemoteModels';
import { DefaultAccountAvatar } from './DefaultAccountAvatar';
@@ -340,7 +340,7 @@ export struct RemoteControlSettingsSheet {
.width('100%')
.height(28)
.fontSize(MobileDesignTypography.labelSmall.size)
- .fontColor(this.permissionModeError.length > 0 ? RED : MUTED)
+ .fontColor(this.permissionModeError.length > 0 ? STATUS_DANGER : MUTED)
.padding({ left: 18, right: 18, top: 4 })
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
@@ -398,7 +398,7 @@ export struct RemoteControlSettingsSheet {
.width('100%')
.fontSize(MobileDesignTypography.titleSmall.size)
.fontWeight(FontWeight.Bold)
- .fontColor(RED)
+ .fontColor(STATUS_DANGER)
Text(RemoteI18n.t('remote.permissions.fullAccessWarningBody'))
.width('100%')
.fontSize(MobileDesignTypography.bodySmall.size)
@@ -425,7 +425,7 @@ export struct RemoteControlSettingsSheet {
.width('100%')
.padding({ left: 16, right: 16, top: 14, bottom: 16 })
.backgroundColor(CARD)
- .border({ width: 1, color: RED })
+ .border({ width: 1, color: STATUS_DANGER })
.borderRadius(18)
.margin({ left: 12, right: 12, bottom: 14 })
}
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/RemoteSessionList.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/RemoteSessionList.ets
index 73cfee96a8..128d462ae6 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/RemoteSessionList.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/RemoteSessionList.ets
@@ -1,7 +1,16 @@
import { MobileDesignTypography } from '../../generated/MobileDesignTokens';
import { RecentWorkspaceEntry, RemoteSession } from '../../model/RemoteModels';
import { RemoteI18n } from '../../i18n/RemoteI18n';
-import { CARD, INK, MUTED, SOFT } from './Theme';
+import {
+ CARD,
+ FLOATING_BORDER,
+ INK,
+ MUTED,
+ SCRIM,
+ SHADOW_MEDIUM,
+ SOFT,
+ TRANSPARENT,
+} from './Theme';
import { SessionActionPresentation, SessionActionSurface } from './SessionActionSurface';
import { AdaptiveSheetOptions } from './AdaptiveSheetOptions';
import {
@@ -271,7 +280,7 @@ export struct RemoteSessionList {
this.ProjectCreateMenu(project.path)
},
placement: Placement.Top,
- popupColor: '#00000000',
+ popupColor: TRANSPARENT,
enableArrow: false,
autoCancel: true,
mask: false,
@@ -325,8 +334,8 @@ export struct RemoteSessionList {
.padding({ top: 8, bottom: 8 })
.backgroundColor(CARD)
.borderRadius(14)
- .border({ width: 1, color: '#18000000' })
- .shadow({ radius: 20, color: '#1A000000', offsetY: 8 })
+ .border({ width: 1, color: FLOATING_BORDER })
+ .shadow({ radius: 20, color: SHADOW_MEDIUM, offsetY: 8 })
}
@Builder
@@ -690,8 +699,8 @@ export struct RemoteSessionList {
private sessionActionSheetOptions(): SheetOptions {
return {
height: 300,
- backgroundColor: '#00000000',
- maskColor: '#44000000',
+ backgroundColor: TRANSPARENT,
+ maskColor: SCRIM,
showClose: false,
dragBar: false
};
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/RemoteSessionRow.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/RemoteSessionRow.ets
index 4a50bc5fb0..abd78bdd6a 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/RemoteSessionRow.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/RemoteSessionRow.ets
@@ -2,7 +2,12 @@ import { MobileDesignTypography } from '../../generated/MobileDesignTokens';
import { RemoteSession } from '../../model/RemoteModels';
import { RemoteI18n } from '../../i18n/RemoteI18n';
import { SessionActionPresentation } from './SessionActionSurface';
-import { INK, MUTED, SOFT } from './Theme';
+import {
+ INK,
+ MUTED,
+ SOFT,
+ TRANSPARENT,
+} from './Theme';
@ComponentV2
export struct RemoteSessionRow {
@@ -55,7 +60,7 @@ export struct RemoteSessionRow {
.height(this.metadata.length > 0 ? 56 : 46)
.padding({ left: this.nested ? 0 : 10, right: 4 })
.alignItems(VerticalAlign.Center)
- .backgroundColor(this.selected ? SOFT : '#00000000')
+ .backgroundColor(this.selected ? SOFT : TRANSPARENT)
.borderRadius(10)
.onTouch((event: TouchEvent) => {
if (this.busy) return;
@@ -69,7 +74,7 @@ export struct RemoteSessionRow {
.bindPopup(this.actionPresentation === SessionActionPresentation.Popover && this.showActionPopover, {
builder: () => { this.actionsPopup() },
placement: Placement.Right,
- popupColor: '#00000000',
+ popupColor: TRANSPARENT,
enableArrow: false,
autoCancel: true,
mask: false,
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SessionActionSurface.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SessionActionSurface.ets
index 411055175f..4dc4a140cd 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SessionActionSurface.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SessionActionSurface.ets
@@ -1,6 +1,6 @@
import { MobileDesignTypography } from '../../generated/MobileDesignTokens';
import { RemoteI18n } from '../../i18n/RemoteI18n';
-import { CARD, INK, LINE, MUTED, RED } from './Theme';
+import { CARD, INK, LINE, MUTED, SHADOW_MEDIUM, STATUS_DANGER, TRANSPARENT } from './Theme';
import { AppActionButton, AppActionStyle } from './AppActionButton';
export enum SessionActionPresentation {
@@ -108,7 +108,7 @@ export struct SessionActionSurface {
.borderRadius(16)
.shadow({
radius: this.presentation === SessionActionPresentation.Popover ? 20 : 0,
- color: this.presentation === SessionActionPresentation.Popover ? '#1A000000' : '#00000000',
+ color: this.presentation === SessionActionPresentation.Popover ? SHADOW_MEDIUM : TRANSPARENT,
offsetY: this.presentation === SessionActionPresentation.Popover ? 8 : 0
})
.alignItems(HorizontalAlign.Center)
@@ -121,7 +121,7 @@ export struct SessionActionSurface {
Text(label)
.layoutWeight(1)
.fontSize(MobileDesignTypography.titleSmall.size)
- .fontColor(destructive ? RED : INK)
+ .fontColor(destructive ? STATUS_DANGER : INK)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
@@ -129,7 +129,7 @@ export struct SessionActionSurface {
.height(46)
.padding({ left: 10, right: 10 })
.borderRadius(8)
- .backgroundColor('#00000000')
+ .backgroundColor(TRANSPARENT)
.onClick(action)
}
@@ -142,7 +142,7 @@ export struct SessionActionSurface {
} else if (kind === 'archive') {
SymbolGlyph($r('sys.symbol.archivebox'))
.fontSize(19)
- .fontColor([destructive ? RED : MUTED])
+ .fontColor([destructive ? STATUS_DANGER : MUTED])
} else if (kind === 'export') {
SymbolGlyph($r('sys.symbol.cloud'))
.fontSize(19)
@@ -150,7 +150,7 @@ export struct SessionActionSurface {
} else {
SymbolGlyph($r('sys.symbol.trash'))
.fontSize(19)
- .fontColor([RED])
+ .fontColor([STATUS_DANGER])
}
}
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SheetCloseButton.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SheetCloseButton.ets
index cde0b444b3..55336f6e5b 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SheetCloseButton.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SheetCloseButton.ets
@@ -1,6 +1,6 @@
import { MobileDesignGeometry } from '../../generated/MobileDesignTokens';
import { RemoteI18n } from '../../i18n/RemoteI18n';
-import { INK } from './Theme';
+import { INK, TRANSPARENT } from './Theme';
/** Quiet top-right close affordance with a full-size touch target. */
@ComponentV2
@@ -19,7 +19,7 @@ export struct SheetCloseButton {
.width(this.touchSize)
.height(this.touchSize)
.padding(0)
- .backgroundColor('#00000000')
+ .backgroundColor(TRANSPARENT)
.borderRadius(12)
.stateEffect(true)
.opacity(this.isEnabled ? 1 : 0.4)
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarDeviceGroup.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarDeviceGroup.ets
index 5c4c1f6e64..d88d1d1cbd 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarDeviceGroup.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarDeviceGroup.ets
@@ -13,7 +13,14 @@ import {
} from '../policy/SessionListProjection';
import { ConversationSessionFilterPolicy } from '../policy/ConversationSessionFilterPolicy';
import { SidebarDirectoryPreviewPolicy } from '../policy/SidebarDirectoryPreviewPolicy';
-import { GREEN, INK, MUTED, SOFT, SUBTLE } from './Theme';
+import {
+ INK,
+ MUTED,
+ SOFT,
+ STATUS_SUCCESS,
+ SUBTLE,
+ TRANSPARENT,
+} from './Theme';
/**
* One keyed disclosure boundary per workspace. Disclosure and request state
@@ -187,7 +194,7 @@ struct SidebarWorkspaceGroup {
Text('')
.width(7)
.height(7)
- .backgroundColor(GREEN)
+ .backgroundColor(STATUS_SUCCESS)
.borderRadius(4)
}
}
@@ -205,7 +212,7 @@ struct SidebarWorkspaceGroup {
.height(44)
.padding({ left: this.bodyIndent + 34, right: 10 })
.alignItems(VerticalAlign.Center)
- .backgroundColor(item.id === this.selectedSessionId ? SOFT : '#00000000')
+ .backgroundColor(item.id === this.selectedSessionId ? SOFT : TRANSPARENT)
.borderRadius(10)
.onClick(() => {
this.onOpenSession(item);
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarGlyphs.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarGlyphs.ets
index 11bdba7192..8ea984d339 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarGlyphs.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarGlyphs.ets
@@ -1,4 +1,4 @@
-import { CARD, GREEN, INK, MUTED } from './Theme';
+import { CARD, STATUS_SUCCESS, INK, MUTED } from './Theme';
import { TemplateIcon } from './TemplateIcon';
@ComponentV2
@@ -46,7 +46,7 @@ export struct SidebarGlyph {
Stack({ alignContent: Alignment.Center }) {
if (this.connectionState === 'connected' || this.connectionState === 'reconnecting') {
TemplateIcon({ src: $r('app.media.remote_ref_sidebar_connected'), iconWidth: 35, iconHeight: 34 })
- Text('').width(8).height(8).backgroundColor(GREEN).borderRadius(4)
+ Text('').width(8).height(8).backgroundColor(STATUS_SUCCESS).borderRadius(4)
.position({ x: 24, y: 22 })
} else {
TemplateIcon({ src: $r('app.media.remote_logo'), iconWidth: 34, iconHeight: 34, tint: MUTED })
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarToggleButton.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarToggleButton.ets
index 0845df285f..341d421f9c 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarToggleButton.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarToggleButton.ets
@@ -1,5 +1,12 @@
import { RemoteI18n } from '../../i18n/RemoteI18n';
-import { CARD, INK, LINE, MUTED } from './Theme';
+import {
+ CARD,
+ INK,
+ LINE,
+ MUTED,
+ SHADOW_SUBTLE,
+ TRANSPARENT,
+} from './Theme';
@ComponentV2
export struct SidebarToggleButton {
@@ -33,12 +40,12 @@ export struct SidebarToggleButton {
}
.width(this.controlSize)
.height(this.controlSize)
- .backgroundColor(this.restore ? CARD : '#00000000')
+ .backgroundColor(this.restore ? CARD : TRANSPARENT)
.border({ width: this.restore ? 1 : 0, color: LINE })
.borderRadius(this.restore ? this.controlSize / 2 : 8)
.shadow({
radius: this.restore ? 14 : 0,
- color: this.restore ? '#12000000' : '#00000000',
+ color: this.restore ? SHADOW_SUBTLE : TRANSPARENT,
offsetY: this.restore ? 5 : 0
})
.accessibilityText(RemoteI18n.t(this.restore ? 'sidebar.restore' : 'sidebar.collapse'))
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarWorkspaceSection.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarWorkspaceSection.ets
index 34290d8221..500c000db5 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarWorkspaceSection.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SidebarWorkspaceSection.ets
@@ -15,7 +15,7 @@ import {
SettingsSheetKind
} from '../policy/SettingsPlacementPolicy';
import { AdaptiveSheetOptions } from './AdaptiveSheetOptions';
-import { GREEN, INK, MUTED, SUBTLE } from './Theme';
+import { STATUS_SUCCESS, INK, MUTED, SUBTLE } from './Theme';
import { SidebarDeviceGroup } from './SidebarDeviceGroup';
import {
SidebarChevronIcon,
@@ -165,7 +165,7 @@ export struct SidebarWorkspaceSection {
Text('')
.width(8)
.height(8)
- .backgroundColor(entry.online ? GREEN : SUBTLE)
+ .backgroundColor(entry.online ? STATUS_SUCCESS : SUBTLE)
.borderRadius(4)
.hitTestBehavior(HitTestMode.None)
}
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SubagentTaskCard.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SubagentTaskCard.ets
index d96e9af28d..396ebcd3e8 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SubagentTaskCard.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/SubagentTaskCard.ets
@@ -2,7 +2,15 @@ import { MobileDesignTypography } from '../../generated/MobileDesignTokens';
import { RemoteI18n } from '../../i18n/RemoteI18n';
import { ConversationUiMessageItem, ConversationUiQuestionAnswer } from '../state/ConversationUiModels';
import { ChatMessageStructurePolicy } from '../policy/ChatMessageStructurePolicy';
-import { CARD, INK, LINE, MUTED, RED, SOFT } from './Theme';
+import {
+ CARD,
+ INK,
+ LINE,
+ MUTED,
+ SOFT,
+ STATUS_DANGER,
+ TRANSPARENT,
+} from './Theme';
import { ThinkingBlock } from './ThinkingBlock';
import { ToolStatusList } from './ToolStatusList';
import { ToolGlyph } from './ToolGlyphs';
@@ -28,13 +36,13 @@ export struct SubagentTaskCard {
Row({ space: 8 }) {
Stack({ alignContent: Alignment.BottomEnd }) {
Stack({ alignContent: Alignment.Center }) {
- ToolGlyph({ kind: 'task', color: this.isError() ? RED : MUTED })
+ ToolGlyph({ kind: 'task', color: this.isError() ? STATUS_DANGER : MUTED })
}
.width(18)
.height(18)
.backgroundColor(SOFT)
.borderRadius(5)
- .border({ width: 1, color: this.isError() ? RED : LINE })
+ .border({ width: 1, color: this.isError() ? STATUS_DANGER : LINE })
if (this.isRunning() || this.isError()) {
Text(this.isError() ? '!' : '•')
.width(10)
@@ -43,7 +51,7 @@ export struct SubagentTaskCard {
.fontWeight(FontWeight.Bold)
.fontColor(CARD)
.textAlign(TextAlign.Center)
- .backgroundColor(this.isError() ? RED : MUTED)
+ .backgroundColor(this.isError() ? STATUS_DANGER : MUTED)
.borderRadius(5)
.border({ width: 1, color: CARD })
}
@@ -52,13 +60,13 @@ export struct SubagentTaskCard {
.height(20)
Text(this.title)
.fontSize(MobileDesignTypography.bodySmall.size)
- .fontColor(this.isError() ? RED : MUTED)
+ .fontColor(this.isError() ? STATUS_DANGER : MUTED)
.layoutWeight(1)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Text(this.statusText())
.fontSize(MobileDesignTypography.labelSmall.size)
- .fontColor(this.isError() ? RED : MUTED)
+ .fontColor(this.isError() ? STATUS_DANGER : MUTED)
.maxLines(1)
if (this.hasProcessItems()) {
SymbolGlyph(this.expanded ? $r('sys.symbol.chevron_up') : $r('sys.symbol.chevron_down'))
@@ -87,7 +95,7 @@ export struct SubagentTaskCard {
top: this.isEmphasized() ? 6 : 0,
bottom: this.isEmphasized() ? 6 : 0
})
- .backgroundColor(this.isEmphasized() || this.expanded ? SOFT : '#00000000')
+ .backgroundColor(this.isEmphasized() || this.expanded ? SOFT : TRANSPARENT)
.borderRadius(this.isEmphasized() ? 14 : 8)
.border({ width: this.isEmphasized() || this.expanded ? 1 : 0, color: LINE })
.accessibilityText(`${this.title}, ${this.statusText()}`)
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/Theme.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/Theme.ets
index c368ccd746..9118db74cf 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/Theme.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/Theme.ets
@@ -1,6 +1,7 @@
export const PAGE_BG: ResourceColor = $r('app.color.page_bg');
/** PAGE_BG at zero alpha, per theme — the transparent end of a fade-out. */
export const PAGE_BG_FADE: ResourceColor = $r('app.color.page_bg_fade');
+export const TRANSPARENT: ResourceColor = $r('app.color.transparent');
export const INK: ResourceColor = $r('app.color.ink');
export const MUTED: ResourceColor = $r('app.color.muted');
export const SUBTLE: ResourceColor = $r('app.color.subtle');
@@ -9,17 +10,27 @@ export const CARD: ResourceColor = $r('app.color.card');
export const ACCENT: ResourceColor = $r('app.color.accent');
export const FILE_LINK: ResourceColor = $r('app.color.file_link');
export const PRIMARY_ACTION: ResourceColor = $r('app.color.primary_action');
-export const PRIMARY_ACTION_TEXT: ResourceColor = $r('app.color.primary_action_text');
+export const CONTENT_ON_ACTION: ResourceColor = $r('app.color.content_on_action');
export const CONNECT_HERO_BG: ResourceColor = $r('app.color.connect_hero_bg');
export const CONNECT_HERO_ACCENT: ResourceColor = $r('app.color.connect_hero_accent');
export const CONNECT_HERO_SECONDARY: ResourceColor = $r('app.color.connect_hero_secondary');
export const CONNECT_HERO_SURFACE: ResourceColor = $r('app.color.connect_hero_surface');
export const CONNECT_SCAN_ACCENT: ResourceColor = $r('app.color.connect_scan_accent');
-export const MODAL_SCRIM: ResourceColor = $r('app.color.modal_scrim');
+export const SCRIM: ResourceColor = $r('app.color.scrim');
+export const SHELL_SCRIM: ResourceColor = $r('app.color.shell_scrim');
+export const MEDIA_BACKGROUND: ResourceColor = $r('app.color.media_background');
+export const MEDIA_SCRIM: ResourceColor = $r('app.color.media_scrim');
+export const MEDIA_CONTROL_BACKGROUND: ResourceColor = $r('app.color.media_control_background');
+export const TOAST_BACKGROUND: ResourceColor = $r('app.color.toast_background');
+export const SHADOW_FAINT: ResourceColor = $r('app.color.shadow_faint');
+export const SHADOW_SUBTLE: ResourceColor = $r('app.color.shadow_subtle');
+export const SHADOW_MEDIUM: ResourceColor = $r('app.color.shadow_medium');
+export const SHADOW_STRONG: ResourceColor = $r('app.color.shadow_strong');
+export const FLOATING_BORDER: ResourceColor = $r('app.color.floating_border');
export const SOFT: ResourceColor = $r('app.color.soft');
export const FLOATING_PANEL_BG: ResourceColor = $r('app.color.floating_panel_bg');
-export const GREEN: ResourceColor = $r('app.color.green');
-export const RED: ResourceColor = $r('app.color.red');
+export const STATUS_SUCCESS: ResourceColor = $r('app.color.status_success');
+export const STATUS_DANGER: ResourceColor = $r('app.color.status_danger');
export const CODE_LINE_NUMBER: ResourceColor = $r('app.color.code_line_number');
export const CODE_KEYWORD: ResourceColor = $r('app.color.code_keyword');
export const CODE_STRING: ResourceColor = $r('app.color.code_string');
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ToolInteractionPanels.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ToolInteractionPanels.ets
index ef53e2c5f5..7eefbd01df 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ToolInteractionPanels.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ToolInteractionPanels.ets
@@ -1,7 +1,7 @@
import { MobileDesignTypography } from '../../generated/MobileDesignTokens';
import { RemoteI18n } from '../../i18n/RemoteI18n';
import { ConversationUiQuestionAnswer } from '../state/ConversationUiModels';
-import { ACCENT, CARD, INK, LINE, MUTED, PRIMARY_ACTION_TEXT, RED, SOFT } from './Theme';
+import { ACCENT, CARD, INK, LINE, MUTED, CONTENT_ON_ACTION, STATUS_DANGER, SOFT } from './Theme';
interface QuestionOption {
label: string;
@@ -42,7 +42,7 @@ export struct ToolConfirmationPanel {
Row({ space: 8 }) {
Text(RemoteI18n.t('chat.approve'))
.fontSize(MobileDesignTypography.labelMedium.size)
- .fontColor(PRIMARY_ACTION_TEXT)
+ .fontColor(CONTENT_ON_ACTION)
.textAlign(TextAlign.Center)
.height(32)
.layoutWeight(1)
@@ -89,7 +89,7 @@ export struct ToolConfirmationPanel {
.backgroundColor(SOFT)
.borderRadius(14)
.padding(10)
- .border({ width: 1, color: this.inputError.length > 0 ? RED : LINE })
+ .border({ width: 1, color: this.inputError.length > 0 ? STATUS_DANGER : LINE })
.defaultFocus(false)
.enabled(true)
.onChange((value: string) => {
@@ -97,7 +97,7 @@ export struct ToolConfirmationPanel {
this.inputError = '';
})
if (this.inputError.length > 0) {
- Text(this.inputError).fontSize(MobileDesignTypography.labelSmall.size).fontColor(RED)
+ Text(this.inputError).fontSize(MobileDesignTypography.labelSmall.size).fontColor(STATUS_DANGER)
}
}
.width('100%')
@@ -160,7 +160,7 @@ export struct ToolQuestionAnswerPanel {
Row() {
Text(RemoteI18n.t('chat.submitAnswer'))
.fontSize(MobileDesignTypography.labelMedium.size)
- .fontColor(this.canSubmit() ? PRIMARY_ACTION_TEXT : MUTED)
+ .fontColor(this.canSubmit() ? CONTENT_ON_ACTION : MUTED)
.textAlign(TextAlign.Center)
.height(32)
.layoutWeight(1)
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ToolStatusList.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ToolStatusList.ets
index 80bc1cb6f3..bc081ce77b 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ToolStatusList.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/ToolStatusList.ets
@@ -5,7 +5,17 @@ import { ToolFileReference, ToolFileReferenceResolver } from '../policy/ToolFile
import { ActivityGroupPolicy, ActivityRowPlan, ActivityThinkingPart } from '../policy/ActivityGroupPolicy';
import { ToolCollapseGroup, ToolCollapsePolicy } from '../policy/ToolCollapsePolicy';
import { ToolStatusPresentationPolicy } from '../policy/ToolStatusPresentationPolicy';
-import { CARD, FILE_LINK, GREEN, INK, LINE, MUTED, RED, SOFT } from './Theme';
+import {
+ CARD,
+ FILE_LINK,
+ INK,
+ LINE,
+ MUTED,
+ SOFT,
+ STATUS_DANGER,
+ STATUS_SUCCESS,
+ TRANSPARENT,
+} from './Theme';
import { ThinkingBlock } from './ThinkingBlock';
import { ToolGlyph } from './ToolGlyphs';
import { ToolConfirmationPanel, ToolQuestionAnswerPanel } from './ToolInteractionPanels';
@@ -120,7 +130,7 @@ export struct ToolStatusList {
this.ToolStatusIcon(tool)
Text(this.toolLineLabel(tool))
.fontSize(MobileDesignTypography.bodySmall.size)
- .fontColor(this.hasToolError(tool) ? RED :
+ .fontColor(this.hasToolError(tool) ? STATUS_DANGER :
(this.toolFilePath(tool).length > 0 ? FILE_LINK : MUTED))
.layoutWeight(1)
.maxLines(1)
@@ -235,7 +245,7 @@ export struct ToolStatusList {
.height(18)
.backgroundColor(this.summaryTypeBg(entry))
.borderRadius(5)
- .border({ width: 1, color: '#00000000' })
+ .border({ width: 1, color: TRANSPARENT })
}
@Builder
@@ -288,7 +298,7 @@ export struct ToolStatusList {
Text(value)
.fontSize(MobileDesignTypography.labelSmall.size)
.lineHeight(MobileDesignTypography.labelSmall.lineHeight)
- .fontColor(isError ? RED : MUTED)
+ .fontColor(isError ? STATUS_DANGER : MUTED)
.width('100%')
.maxLines(5)
.textOverflow({ overflow: TextOverflow.Ellipsis })
@@ -329,7 +339,7 @@ export struct ToolStatusList {
if (this.isEmphasizedToolRow(tool, index)) {
return SOFT;
}
- return '#00000000';
+ return TRANSPARENT;
}
private toolRowBorderWidth(tool: ConversationUiToolStatus, index: number): number {
@@ -719,10 +729,10 @@ export struct ToolStatusList {
private toolTypeColor(tool: ConversationUiToolStatus): ResourceColor {
if (this.isDeleteTool(tool)) {
- return RED;
+ return STATUS_DANGER;
}
if (this.isTodoTool(tool) || this.isFileCreateTool(tool)) {
- return GREEN;
+ return STATUS_SUCCESS;
}
return MUTED;
}
@@ -733,7 +743,7 @@ export struct ToolStatusList {
private toolTypeBorderColor(tool: ConversationUiToolStatus): ResourceColor {
if (this.hasToolError(tool)) {
- return RED;
+ return STATUS_DANGER;
}
return LINE;
}
@@ -757,7 +767,7 @@ export struct ToolStatusList {
private toolStatusColor(tool: ConversationUiToolStatus): ResourceColor {
if (this.hasToolError(tool)) {
- return RED;
+ return STATUS_DANGER;
}
return MUTED;
}
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/WatchProvisionCard.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/WatchProvisionCard.ets
index e627539e1f..35fe15f1e4 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/WatchProvisionCard.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/WatchProvisionCard.ets
@@ -1,7 +1,7 @@
import { MobileDesignTypography } from '../../generated/MobileDesignTokens';
import { RemoteI18n } from '../../i18n/RemoteI18n';
import { WatchProvisionPhase, WatchProvisionState } from '../state/WatchProvisionState';
-import { CARD, GREEN, INK, LINE, MODAL_SCRIM, MUTED, PRIMARY_ACTION, PRIMARY_ACTION_TEXT, RED, SOFT,
+import { CARD, STATUS_SUCCESS, INK, LINE, SCRIM, MUTED, PRIMARY_ACTION, CONTENT_ON_ACTION, STATUS_DANGER, SOFT,
SUBTLE } from './Theme';
/**
@@ -23,7 +23,7 @@ export struct WatchProvisionCard {
Text('')
.width('100%')
.height('100%')
- .backgroundColor(MODAL_SCRIM)
+ .backgroundColor(SCRIM)
.onClick(() => {
// Tapping away while the desktop is minting would leave the watch
// with no answer and no card to explain it.
@@ -88,7 +88,7 @@ export struct WatchProvisionCard {
Text(this.state.message)
.fontSize(MobileDesignTypography.bodySmall.size)
.lineHeight(MobileDesignTypography.bodySmall.lineHeight)
- .fontColor(RED)
+ .fontColor(STATUS_DANGER)
.width('100%')
}
}
@@ -110,7 +110,7 @@ export struct WatchProvisionCard {
Text(this.state.message)
.fontSize(MobileDesignTypography.bodyLarge.size)
.lineHeight(MobileDesignTypography.bodyLarge.lineHeight)
- .fontColor(this.state.phase === WatchProvisionPhase.Done ? GREEN : RED)
+ .fontColor(this.state.phase === WatchProvisionPhase.Done ? STATUS_SUCCESS : STATUS_DANGER)
.width('100%')
}
@@ -130,7 +130,7 @@ export struct WatchProvisionCard {
.height(56)
.fontSize(MobileDesignTypography.labelLarge.size)
.fontWeight(FontWeight.Bold)
- .fontColor(PRIMARY_ACTION_TEXT)
+ .fontColor(CONTENT_ON_ACTION)
.backgroundColor(PRIMARY_ACTION)
.borderRadius(28)
.onClick(() => { this.onApprove(''); })
@@ -155,7 +155,7 @@ export struct WatchProvisionCard {
.height(56)
.fontSize(MobileDesignTypography.labelLarge.size)
.fontWeight(FontWeight.Bold)
- .fontColor(PRIMARY_ACTION_TEXT)
+ .fontColor(CONTENT_ON_ACTION)
.backgroundColor(PRIMARY_ACTION)
.borderRadius(28)
.enabled(this.password.length > 0)
@@ -173,7 +173,7 @@ export struct WatchProvisionCard {
.height(56)
.fontSize(MobileDesignTypography.labelLarge.size)
.fontWeight(FontWeight.Bold)
- .fontColor(PRIMARY_ACTION_TEXT)
+ .fontColor(CONTENT_ON_ACTION)
.backgroundColor(PRIMARY_ACTION)
.borderRadius(28)
.onClick(this.onDismiss)
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/WideConversationHost.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/WideConversationHost.ets
index 97d6028435..9af1b41574 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/WideConversationHost.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/WideConversationHost.ets
@@ -26,7 +26,12 @@ import {
} from './remote/RemoteSurfaceHost';
import { SidebarToggleButton } from './SidebarToggleButton';
import { SidebarWorkspaceSection } from './SidebarWorkspaceSection';
-import { FLOATING_PANEL_BG, LINE, PAGE_BG } from './Theme';
+import {
+ FLOATING_PANEL_BG,
+ LINE,
+ PAGE_BG,
+ SHADOW_SUBTLE,
+} from './Theme';
const WIDE_DETAIL_CONTENT_MAX_WIDTH: number = 920;
@@ -171,7 +176,7 @@ export struct WideConversationHost {
}
.width('100%').height('100%').backgroundColor(FLOATING_PANEL_BG)
.borderRadius(18).clip(true)
- .shadow({ radius: 24, color: '#14000000', offsetX: 4, offsetY: 8 })
+ .shadow({ radius: 24, color: SHADOW_SUBTLE, offsetX: 4, offsetY: 8 })
}
.width(WideLayoutGeometry.masterPaneWidth(this.filePreviewLayout, this.wideMasterPaneWidth))
.height('100%').padding({ left: 10, right: 6, top: 10, bottom: 10 }).backgroundColor(PAGE_BG)
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/remote/RemoteSurfaceHost.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/remote/RemoteSurfaceHost.ets
index 705b8996d7..cb610ea4d2 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/remote/RemoteSurfaceHost.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/components/remote/RemoteSurfaceHost.ets
@@ -20,7 +20,7 @@ import {
SettingsPlacementPolicy,
SettingsSheetKind
} from '../../policy/SettingsPlacementPolicy';
-import { CARD, GREEN, INK, LINE, MUTED, PAGE_BG, PRIMARY_ACTION, PRIMARY_ACTION_TEXT, RED } from '../Theme';
+import { CARD, STATUS_SUCCESS, INK, LINE, MUTED, PAGE_BG, PRIMARY_ACTION, CONTENT_ON_ACTION, STATUS_DANGER } from '../Theme';
export enum RemoteSurfaceMode {
Master = 'master',
@@ -150,7 +150,7 @@ export struct RemoteSurfaceHost {
Text(RemoteI18n.t('remote.settings.reconnect'))
.fontSize(MobileDesignTypography.bodySmall.size)
.fontWeight(FontWeight.Medium)
- .fontColor(PRIMARY_ACTION_TEXT)
+ .fontColor(CONTENT_ON_ACTION)
.height(28)
.padding({ left: 12, right: 12 })
.backgroundColor(PRIMARY_ACTION)
@@ -194,7 +194,7 @@ export struct RemoteSurfaceHost {
Text(RemoteI18n.t('remote.connectText'))
.fontSize(MobileDesignTypography.bodySmall.size).lineHeight(MobileDesignTypography.bodySmall.lineHeight).fontColor(MUTED).textAlign(TextAlign.Center)
Text(RemoteI18n.t('connect.connect'))
- .width(136).height(44).fontSize(MobileDesignTypography.titleSmall.size).fontColor(PRIMARY_ACTION_TEXT)
+ .width(136).height(44).fontSize(MobileDesignTypography.titleSmall.size).fontColor(CONTENT_ON_ACTION)
.backgroundColor(PRIMARY_ACTION).textAlign(TextAlign.Center).borderRadius(22)
.onClick(() => this.actions.onRemoteHome.connectWorkspace())
}
@@ -244,13 +244,13 @@ export struct RemoteSurfaceHost {
if (this.canReconnect()) {
Text(RemoteI18n.t('remote.settings.reconnect'))
.width(148).height(46).fontSize(MobileDesignTypography.titleSmall.size).fontWeight(FontWeight.Medium)
- .fontColor(PRIMARY_ACTION_TEXT).backgroundColor(PRIMARY_ACTION)
+ .fontColor(CONTENT_ON_ACTION).backgroundColor(PRIMARY_ACTION)
.textAlign(TextAlign.Center).borderRadius(23).margin({ top: 12 })
.onClick(() => this.actions.onRemoteHome.reconnect())
} else {
Text(RemoteI18n.t('remote.startSession'))
.width(148).height(46).fontSize(MobileDesignTypography.titleSmall.size).fontWeight(FontWeight.Medium)
- .fontColor(PRIMARY_ACTION_TEXT).backgroundColor(PRIMARY_ACTION)
+ .fontColor(CONTENT_ON_ACTION).backgroundColor(PRIMARY_ACTION)
.textAlign(TextAlign.Center).borderRadius(23).margin({ top: 12 })
.onClick(() => this.createSession('code'))
}
@@ -401,9 +401,9 @@ export struct RemoteSurfaceHost {
}
private statusColor(): ResourceColor {
- if (this.remotePageState.connectionState === 'connected') return GREEN;
+ if (this.remotePageState.connectionState === 'connected') return STATUS_SUCCESS;
if (this.remotePageState.connectionState === 'failed' || this.remotePageState.connectionState === 'disconnected') {
- return RED;
+ return STATUS_DANGER;
}
return MUTED;
}
diff --git a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/preview/MobileDesignGallery.ets b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/preview/MobileDesignGallery.ets
index 08c1801201..0931b6fb20 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/ets/pages/preview/MobileDesignGallery.ets
+++ b/src/apps/mobile/harmonyos/entry/src/main/ets/pages/preview/MobileDesignGallery.ets
@@ -6,7 +6,7 @@ import {
} from '../../generated/MobilePreviewScenarios';
import { ComposerBar, ComposerPresentation } from '../components/ComposerBar';
import { ConversationHeader } from '../components/ConversationHeader';
-import { INK, LINE, MUTED, PAGE_BG, SOFT } from '../components/Theme';
+import { INK, LINE, MUTED, PAGE_BG, SOFT, TRANSPARENT } from '../components/Theme';
@Entry
@ComponentV2
@@ -104,7 +104,7 @@ struct MobileDesignGallery {
top: message.role === 'user' ? MobileDesignGeometry.messageBubbleVerticalPadding : 2,
bottom: message.role === 'user' ? MobileDesignGeometry.messageBubbleVerticalPadding : 2
})
- .backgroundColor(message.role === 'user' ? SOFT : '#00000000')
+ .backgroundColor(message.role === 'user' ? SOFT : TRANSPARENT)
.borderRadius(message.role === 'user' ? MobileDesignGeometry.messageBubbleRadius : 0)
if (message.role !== 'user') {
Blank()
diff --git a/src/apps/mobile/harmonyos/entry/src/main/resources/base/element/color.json b/src/apps/mobile/harmonyos/entry/src/main/resources/base/element/color.json
index cdce3f4543..46f9729710 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/resources/base/element/color.json
+++ b/src/apps/mobile/harmonyos/entry/src/main/resources/base/element/color.json
@@ -4,6 +4,10 @@
"name": "start_window_background",
"value": "#FFFFFF"
},
+ {
+ "name": "transparent",
+ "value": "#00000000"
+ },
{
"name": "page_bg",
"value": "#FFFFFF"
@@ -45,7 +49,7 @@
"value": "#111111"
},
{
- "name": "primary_action_text",
+ "name": "content_on_action",
"value": "#FFFFFF"
},
{
@@ -69,9 +73,49 @@
"value": "#FFD021"
},
{
- "name": "modal_scrim",
+ "name": "scrim",
"value": "#44000000"
},
+ {
+ "name": "shell_scrim",
+ "value": "#24000000"
+ },
+ {
+ "name": "media_background",
+ "value": "#FF000000"
+ },
+ {
+ "name": "media_scrim",
+ "value": "#B8000000"
+ },
+ {
+ "name": "media_control_background",
+ "value": "#8C000000"
+ },
+ {
+ "name": "toast_background",
+ "value": "#D1171717"
+ },
+ {
+ "name": "shadow_faint",
+ "value": "#08000000"
+ },
+ {
+ "name": "shadow_subtle",
+ "value": "#12000000"
+ },
+ {
+ "name": "shadow_medium",
+ "value": "#18000000"
+ },
+ {
+ "name": "shadow_strong",
+ "value": "#24000000"
+ },
+ {
+ "name": "floating_border",
+ "value": "#18000000"
+ },
{
"name": "soft",
"value": "#F4F3F0"
@@ -81,11 +125,11 @@
"value": "#F7F7F5"
},
{
- "name": "green",
+ "name": "status_success",
"value": "#27C46A"
},
{
- "name": "red",
+ "name": "status_danger",
"value": "#E04F4F"
},
{
diff --git a/src/apps/mobile/harmonyos/entry/src/main/resources/dark/element/color.json b/src/apps/mobile/harmonyos/entry/src/main/resources/dark/element/color.json
index e29074a8f5..6d08d86a85 100644
--- a/src/apps/mobile/harmonyos/entry/src/main/resources/dark/element/color.json
+++ b/src/apps/mobile/harmonyos/entry/src/main/resources/dark/element/color.json
@@ -4,6 +4,10 @@
"name": "start_window_background",
"value": "#000000"
},
+ {
+ "name": "transparent",
+ "value": "#00000000"
+ },
{
"name": "page_bg",
"value": "#151514"
@@ -45,7 +49,7 @@
"value": "#454540"
},
{
- "name": "primary_action_text",
+ "name": "content_on_action",
"value": "#FFFFFF"
},
{
@@ -69,9 +73,49 @@
"value": "#FFD021"
},
{
- "name": "modal_scrim",
+ "name": "scrim",
"value": "#44000000"
},
+ {
+ "name": "shell_scrim",
+ "value": "#24000000"
+ },
+ {
+ "name": "media_background",
+ "value": "#FF000000"
+ },
+ {
+ "name": "media_scrim",
+ "value": "#B8000000"
+ },
+ {
+ "name": "media_control_background",
+ "value": "#8C000000"
+ },
+ {
+ "name": "toast_background",
+ "value": "#D1171717"
+ },
+ {
+ "name": "shadow_faint",
+ "value": "#08000000"
+ },
+ {
+ "name": "shadow_subtle",
+ "value": "#12000000"
+ },
+ {
+ "name": "shadow_medium",
+ "value": "#18000000"
+ },
+ {
+ "name": "shadow_strong",
+ "value": "#24000000"
+ },
+ {
+ "name": "floating_border",
+ "value": "#18000000"
+ },
{
"name": "soft",
"value": "#2D2C28"
@@ -81,11 +125,11 @@
"value": "#1E1E1C"
},
{
- "name": "green",
+ "name": "status_success",
"value": "#3BD47B"
},
{
- "name": "red",
+ "name": "status_danger",
"value": "#FF6B6B"
},
{
diff --git a/src/apps/mobile/ios/BitFun/Features/Account/AccountSettingsView.swift b/src/apps/mobile/ios/BitFun/Features/Account/AccountSettingsView.swift
index 1dd2a2332d..64f73489e9 100644
--- a/src/apps/mobile/ios/BitFun/Features/Account/AccountSettingsView.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Account/AccountSettingsView.swift
@@ -59,7 +59,7 @@ struct AccountSettingsView: View {
if let error = model.coreErrorMessage, !error.isEmpty {
Text(error)
.font(.system(size: 13))
- .foregroundStyle(BitFunTheme.red)
+ .foregroundStyle(BitFunTheme.statusDanger)
.padding(.top, 12)
}
@@ -68,11 +68,11 @@ struct AccountSettingsView: View {
password = ""
} label: {
HStack(spacing: 8) {
- if model.accountBusy { ProgressView().tint(.white) }
+ if model.accountBusy { ProgressView().tint(BitFunTheme.contentOnAction) }
Text(model.localized(model.accountBusy ? "正在登录" : "登录"))
}
.font(.system(size: 17, weight: .bold))
- .foregroundStyle(.white)
+ .foregroundStyle(BitFunTheme.contentOnAction)
.frame(maxWidth: .infinity, minHeight: 56)
.background(canLogin ? BitFunTheme.accent : BitFunTheme.muted.opacity(0.35))
.clipShape(RoundedRectangle(cornerRadius: 18))
@@ -117,11 +117,11 @@ struct AccountSettingsView: View {
Button { model.retryAccountFailure() } label: {
HStack(spacing: 8) {
- if model.accountBusy { ProgressView().tint(.white) }
+ if model.accountBusy { ProgressView().tint(BitFunTheme.contentOnAction) }
Text(model.localized(model.accountBusy ? "正在重试" : "重试加载设备"))
}
.font(.system(size: 17, weight: .bold))
- .foregroundStyle(.white)
+ .foregroundStyle(BitFunTheme.contentOnAction)
.frame(maxWidth: .infinity, minHeight: 56)
.background(BitFunTheme.accent)
.clipShape(RoundedRectangle(cornerRadius: 18))
@@ -184,7 +184,7 @@ struct AccountSettingsView: View {
Spacer()
Text(model.localized("已登录"))
.font(.system(size: 14))
- .foregroundStyle(BitFunTheme.green)
+ .foregroundStyle(BitFunTheme.statusSuccess)
}
Text(model.localizedFormat("当前以 %@ 登录。", model.accountUser ?? ""))
.font(.system(size: 14))
@@ -259,7 +259,7 @@ struct AccountSettingsView: View {
} label: {
Text(model.localized("退出账号"))
.font(.system(size: 16, weight: .medium))
- .foregroundStyle(BitFunTheme.red)
+ .foregroundStyle(BitFunTheme.statusDanger)
.frame(maxWidth: .infinity, minHeight: 54)
.background(BitFunTheme.card)
.clipShape(RoundedRectangle(cornerRadius: 16))
@@ -344,13 +344,13 @@ struct SettingsDeviceRow: View {
.lineLimit(1)
Text(MobileLocalization.text(device.online ? "在线" : "离线"))
.font(.system(size: 12))
- .foregroundStyle(device.online ? BitFunTheme.green : BitFunTheme.muted)
+ .foregroundStyle(device.online ? BitFunTheme.statusSuccess : BitFunTheme.muted)
}
Spacer(minLength: 12)
if device.selected {
Image(systemName: "checkmark.circle.fill")
.font(.system(size: 18))
- .foregroundStyle(BitFunTheme.green)
+ .foregroundStyle(BitFunTheme.statusSuccess)
} else {
Image(systemName: "chevron.right")
.font(.system(size: 14, weight: .medium))
diff --git a/src/apps/mobile/ios/BitFun/Features/Chat/ChatTimelineView.swift b/src/apps/mobile/ios/BitFun/Features/Chat/ChatTimelineView.swift
index d2f5f7b76d..e87810eba4 100644
--- a/src/apps/mobile/ios/BitFun/Features/Chat/ChatTimelineView.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Chat/ChatTimelineView.swift
@@ -29,7 +29,7 @@ struct ChatTimelineView: View {
if model.timelineRows.isEmpty && model.isSending {
TypingIndicator().frame(maxWidth: .infinity, alignment: .leading)
}
- Color.clear.frame(height: 1).id("timeline-bottom")
+ BitFunTheme.transparent.frame(height: 1).id("timeline-bottom")
}
.padding(.horizontal, MobileDesignGeometry.contentGutter)
.padding(.top, MobileDesignGeometry.timelineTopPadding)
@@ -61,7 +61,7 @@ struct ChatTimelineView: View {
.background(BitFunTheme.card)
.clipShape(Circle())
.overlay(Circle().stroke(BitFunTheme.line, lineWidth: 1))
- .shadow(color: .black.opacity(0.09), radius: 8, y: 3)
+ .shadow(color: BitFunTheme.shadowMedium, radius: 8, y: 3)
}
.buttonStyle(.plain)
.padding(18)
@@ -112,7 +112,7 @@ private struct ConversationRowView: View {
Button { model.retryMessage(row.text) } label: {
Label(model.localized("重新发送"), systemImage: "arrow.clockwise")
.font(MobileDesignTypography.labelSmall.font)
- .foregroundStyle(BitFunTheme.red)
+ .foregroundStyle(BitFunTheme.statusDanger)
}
.buttonStyle(.plain)
}
@@ -143,7 +143,7 @@ private struct ConversationRowView: View {
Button { model.retryMessage(row.text) } label: {
Label(model.localized("重试"), systemImage: "arrow.clockwise")
.font(MobileDesignTypography.labelSmall.font)
- .foregroundStyle(BitFunTheme.red)
+ .foregroundStyle(BitFunTheme.statusDanger)
}
.buttonStyle(.plain)
}
@@ -415,7 +415,7 @@ private struct FileReferenceCard: View {
.foregroundStyle(BitFunTheme.muted).lineLimit(1)
if let status = model.downloadStatus(for: reference.remotePath) {
Text(status).font(MobileDesignTypography.labelSmall.font)
- .foregroundStyle(model.downloadPhase == .failed ? BitFunTheme.red : BitFunTheme.muted)
+ .foregroundStyle(model.downloadPhase == .failed ? BitFunTheme.statusDanger : BitFunTheme.muted)
.lineLimit(1)
}
}
@@ -478,11 +478,11 @@ private struct FullScreenTimelineImage: View {
var body: some View {
ZStack(alignment: .topTrailing) {
- Color.black.ignoresSafeArea()
+ BitFunTheme.mediaBackground.ignoresSafeArea()
if let uiImage = image.uiImage { Image(uiImage: uiImage).resizable().scaledToFit().ignoresSafeArea() }
Button { dismiss() } label: {
- Image(systemName: "xmark").font(.system(size: 15, weight: .semibold)).foregroundStyle(.white)
- .frame(width: 44, height: 44).background(Color.black.opacity(0.55)).clipShape(Circle())
+ Image(systemName: "xmark").font(.system(size: 15, weight: .semibold)).foregroundStyle(BitFunTheme.contentOnAction)
+ .frame(width: 44, height: 44).background(BitFunTheme.mediaControlBackground).clipShape(Circle())
}
.buttonStyle(.plain).padding(20)
}
@@ -624,14 +624,14 @@ private struct ToolStatusRow: View {
if tool.actions.contains("CANCEL") {
Button { model.cancelTool(tool.id) } label: {
Text(model.localized("停止执行"))
- .font(MobileDesignTypography.labelMedium.font).foregroundStyle(BitFunTheme.red)
+ .font(MobileDesignTypography.labelMedium.font).foregroundStyle(BitFunTheme.statusDanger)
.frame(maxWidth: .infinity, minHeight: 40).background(BitFunTheme.card).clipShape(Capsule())
- .overlay(Capsule().stroke(BitFunTheme.red.opacity(0.5), lineWidth: 1))
+ .overlay(Capsule().stroke(BitFunTheme.statusDanger.opacity(0.5), lineWidth: 1))
}
.buttonStyle(.plain)
}
}
- .padding(emphasized ? 10 : 0).background(emphasized ? BitFunTheme.soft : Color.clear)
+ .padding(emphasized ? 10 : 0).background(emphasized ? BitFunTheme.soft : BitFunTheme.transparent)
.clipShape(RoundedRectangle(cornerRadius: 14))
.overlay { if emphasized { RoundedRectangle(cornerRadius: 14).stroke(BitFunTheme.line, lineWidth: 1) } }
}
@@ -646,7 +646,7 @@ private struct ToolStatusRow: View {
.overlay(RoundedRectangle(cornerRadius: 11).stroke(BitFunTheme.line, lineWidth: 1))
Button { model.answerTool(tool.id, answer: answer); answer = "" } label: {
Text(model.localized("发送回复"))
- .font(MobileDesignTypography.labelMedium.font).foregroundStyle(.white)
+ .font(MobileDesignTypography.labelMedium.font).foregroundStyle(BitFunTheme.contentOnAction)
.frame(maxWidth: .infinity, minHeight: 40)
.background(answer.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || model.busy ? BitFunTheme.muted : BitFunTheme.accent)
.clipShape(Capsule())
@@ -696,10 +696,10 @@ private struct ToolStatusRow: View {
}
Button { submitStructuredAnswers() } label: {
HStack {
- if model.busy { ProgressView().controlSize(.small).tint(.white) }
+ if model.busy { ProgressView().controlSize(.small).tint(BitFunTheme.contentOnAction) }
Text(model.localized("发送回复"))
}
- .font(MobileDesignTypography.labelMedium.font).foregroundStyle(.white)
+ .font(MobileDesignTypography.labelMedium.font).foregroundStyle(BitFunTheme.contentOnAction)
.frame(maxWidth: .infinity, minHeight: 40)
.background(structuredAnswersValid && !model.busy ? BitFunTheme.accent : BitFunTheme.muted)
.clipShape(Capsule())
@@ -770,7 +770,7 @@ private struct ToolStatusRow: View {
private func toolAction(_ label: String, primary: Bool, action: @escaping () -> Void) -> some View {
Button(action: action) {
Text(label).font(MobileDesignTypography.labelMedium.font)
- .foregroundStyle(primary ? Color.white : BitFunTheme.ink)
+ .foregroundStyle(primary ? BitFunTheme.contentOnAction : BitFunTheme.ink)
.frame(maxWidth: .infinity, minHeight: 40).background(primary ? BitFunTheme.accent : BitFunTheme.card)
.clipShape(Capsule()).overlay { if !primary { Capsule().stroke(BitFunTheme.line, lineWidth: 1) } }
}
@@ -826,7 +826,7 @@ private struct ToolStatusRow: View {
}
private var statusColor: Color {
- switch tool.phase { case "FAILED": BitFunTheme.red; case "COMPLETED": BitFunTheme.green; default: BitFunTheme.muted }
+ switch tool.phase { case "FAILED": BitFunTheme.statusDanger; case "COMPLETED": BitFunTheme.statusSuccess; default: BitFunTheme.muted }
}
private var statusMark: String {
diff --git a/src/apps/mobile/ios/BitFun/Features/Chat/ComposerBar.swift b/src/apps/mobile/ios/BitFun/Features/Chat/ComposerBar.swift
index c0a74f7c49..3da7c24d36 100644
--- a/src/apps/mobile/ios/BitFun/Features/Chat/ComposerBar.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Chat/ComposerBar.swift
@@ -62,7 +62,7 @@ struct ComposerBar: View {
: MobileDesignGeometry.composerCollapsedRadius
)
)
- .shadow(color: .black.opacity(0.05), radius: 10, y: 2)
+ .shadow(color: BitFunTheme.shadowSubtle, radius: 10, y: 2)
.padding(.horizontal, MobileDesignGeometry.contentGutter)
.padding(.top, 8)
.padding(.bottom, 14)
@@ -184,7 +184,7 @@ struct ComposerBar: View {
"",
text: $model.draft,
prompt: Text(speech.isListening ? model.localized("正在聆听") : placeholder)
- .foregroundColor(speech.isListening ? BitFunTheme.green : BitFunTheme.muted),
+ .foregroundColor(speech.isListening ? BitFunTheme.statusSuccess : BitFunTheme.muted),
axis: .vertical
)
.font(MobileDesignTypography.bodyLarge.font)
@@ -199,10 +199,10 @@ struct ComposerBar: View {
}
.padding(.leading, speech.isListening ? 12 : 4)
.padding(.trailing, 4)
- .background(speech.isListening ? BitFunTheme.soft : Color.clear)
+ .background(speech.isListening ? BitFunTheme.soft : BitFunTheme.transparent)
.overlay(
RoundedRectangle(cornerRadius: 20)
- .stroke(speech.isListening ? BitFunTheme.green : Color.clear, lineWidth: 1)
+ .stroke(speech.isListening ? BitFunTheme.statusSuccess : BitFunTheme.transparent, lineWidth: 1)
)
.clipShape(RoundedRectangle(cornerRadius: 20))
}
@@ -292,9 +292,9 @@ struct ComposerBar: View {
Button { model.removeComposerImage(id: attachment.id) } label: {
Image(systemName: "xmark")
.font(.system(size: 9, weight: .bold))
- .foregroundStyle(Color.white)
+ .foregroundStyle(BitFunTheme.contentOnAction)
.frame(width: 20, height: 20)
- .background(Color.black.opacity(0.72))
+ .background(BitFunTheme.mediaScrim)
.clipShape(Circle())
}
.buttonStyle(.plain)
@@ -343,7 +343,7 @@ struct ComposerBar: View {
HStack(spacing: 10) {
Image(systemName: option.selected ? "checkmark.circle" : "circle")
.font(.system(size: 16))
- .foregroundStyle(option.selected ? BitFunTheme.ink : Color.clear)
+ .foregroundStyle(option.selected ? BitFunTheme.ink : BitFunTheme.transparent)
.frame(width: 20, height: 20)
VStack(alignment: .leading, spacing: 2) {
Text(option.primaryLabel)
@@ -359,7 +359,7 @@ struct ComposerBar: View {
}
.padding(.horizontal, 10)
.frame(height: MobileDesignGeometry.composerModelSelectorRowHeight)
- .background(option.selected ? BitFunTheme.soft : Color.clear)
+ .background(option.selected ? BitFunTheme.soft : BitFunTheme.transparent)
.clipShape(
RoundedRectangle(
cornerRadius: MobileDesignGeometry.composerModelSelectorRowRadius
@@ -447,7 +447,7 @@ private struct ListeningWave: View {
HStack(spacing: 2) {
ForEach([8.0, 14.0, 10.0, 17.0], id: \.self) { height in
Capsule()
- .fill(BitFunTheme.green)
+ .fill(BitFunTheme.statusSuccess)
.frame(width: 2, height: height)
}
}
diff --git a/src/apps/mobile/ios/BitFun/Features/Chat/ConversationHeader.swift b/src/apps/mobile/ios/BitFun/Features/Chat/ConversationHeader.swift
index b8b4e138b1..e978062fd2 100644
--- a/src/apps/mobile/ios/BitFun/Features/Chat/ConversationHeader.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Chat/ConversationHeader.swift
@@ -31,12 +31,12 @@ struct ConversationHeader: View {
.background(BitFunTheme.card)
.overlay(Circle().stroke(BitFunTheme.line, lineWidth: 1))
.clipShape(Circle())
- .shadow(color: .black.opacity(0.07), radius: 8, y: 3)
+ .shadow(color: BitFunTheme.shadowMedium, radius: 8, y: 3)
}
.buttonStyle(.plain)
.accessibilityLabel(MobileLocalization.text(sidebarActionLabel))
} else {
- Color.clear
+ BitFunTheme.transparent
.frame(
width: MobileDesignGeometry.controlTouchSize,
height: MobileDesignGeometry.controlTouchSize
@@ -70,7 +70,7 @@ struct ConversationHeader: View {
if model.selectedSession != nil {
actionsMenu
} else {
- Color.clear
+ BitFunTheme.transparent
.frame(
width: MobileDesignGeometry.controlTouchSize,
height: MobileDesignGeometry.controlTouchSize
@@ -109,7 +109,7 @@ struct ConversationHeader: View {
.background(BitFunTheme.card)
.overlay(Circle().stroke(BitFunTheme.line, lineWidth: 1))
.clipShape(Circle())
- .shadow(color: .black.opacity(0.07), radius: 8, y: 3)
+ .shadow(color: BitFunTheme.shadowMedium, radius: 8, y: 3)
}
.buttonStyle(.plain)
.accessibilityLabel(model.localized("会话操作"))
@@ -153,7 +153,7 @@ struct ConversationHeader: View {
Button(action: action) {
Text(model.localized(title))
.font(.system(size: 13, weight: .medium))
- .foregroundStyle(primary && enabled ? Color.white : BitFunTheme.ink)
+ .foregroundStyle(primary && enabled ? BitFunTheme.contentOnAction : BitFunTheme.ink)
.frame(width: 52, height: 42)
.background(primary && enabled ? BitFunTheme.accent : BitFunTheme.soft)
.clipShape(RoundedRectangle(cornerRadius: 14))
@@ -230,7 +230,7 @@ struct ConversationActionsPopover: View {
}
.padding(.horizontal, 8)
.frame(height: MobileDesignGeometry.popoverActionHeight)
- .background(selected ? BitFunTheme.soft : Color.clear)
+ .background(selected ? BitFunTheme.soft : BitFunTheme.transparent)
.clipShape(RoundedRectangle(cornerRadius: 10))
}
.buttonStyle(.plain)
diff --git a/src/apps/mobile/ios/BitFun/Features/DesignSystem/AdaptiveModalComponents.swift b/src/apps/mobile/ios/BitFun/Features/DesignSystem/AdaptiveModalComponents.swift
index 7412027386..6f55a1c2f3 100644
--- a/src/apps/mobile/ios/BitFun/Features/DesignSystem/AdaptiveModalComponents.swift
+++ b/src/apps/mobile/ios/BitFun/Features/DesignSystem/AdaptiveModalComponents.swift
@@ -80,7 +80,7 @@ struct BitFunModalCard: View {
.clipShape(RoundedRectangle(cornerRadius: radius))
.overlay(
RoundedRectangle(cornerRadius: radius)
- .stroke(bordered ? BitFunTheme.line : Color.clear, lineWidth: 1)
+ .stroke(bordered ? BitFunTheme.line : BitFunTheme.transparent, lineWidth: 1)
)
}
}
@@ -117,7 +117,7 @@ struct SignedOutConnectionActions: View {
Button(action: onOpenAccount) {
Text(accountTitle)
.font(.system(size: fontSize, weight: .bold))
- .foregroundStyle(.white)
+ .foregroundStyle(BitFunTheme.contentOnAction)
.frame(maxWidth: .infinity, minHeight: buttonHeight)
.background(BitFunTheme.accent)
.clipShape(Capsule())
@@ -240,7 +240,7 @@ private struct BitFunAdaptiveModalModifier: ViewModifier {
@ViewBuilder
private var sideCover: some View {
let cover = ZStack(alignment: .trailing) {
- MobileDesignColors.modalScrim
+ BitFunTheme.scrim
.ignoresSafeArea()
.contentShape(Rectangle())
.onTapGesture { isPresented = false }
@@ -264,11 +264,11 @@ private struct BitFunAdaptiveModalModifier: ViewModifier {
)
.stroke(BitFunTheme.line, lineWidth: 1)
)
- .shadow(color: .black.opacity(0.14), radius: 18, x: -5, y: 8)
+ .shadow(color: BitFunTheme.shadowStrong, radius: 18, x: -5, y: 8)
.accessibilityAddTraits(.isModal)
}
if #available(iOS 16.4, *) {
- cover.presentationBackground(.clear)
+ cover.presentationBackground(BitFunTheme.transparent)
} else {
cover
}
diff --git a/src/apps/mobile/ios/BitFun/Features/DesignSystem/GeneratedMobileDesignTokens.swift b/src/apps/mobile/ios/BitFun/Features/DesignSystem/GeneratedMobileDesignTokens.swift
index 29476555d0..5e770be879 100644
--- a/src/apps/mobile/ios/BitFun/Features/DesignSystem/GeneratedMobileDesignTokens.swift
+++ b/src/apps/mobile/ios/BitFun/Features/DesignSystem/GeneratedMobileDesignTokens.swift
@@ -13,6 +13,7 @@ struct MobileTypographyToken {
enum MobileDesignColors {
static let startWindowBackground = dynamic(light: 0xFFFFFFFF, dark: 0xFF000000)
+ static let transparent = dynamic(light: 0x00000000, dark: 0x00000000)
static let pageBg = dynamic(light: 0xFFFFFFFF, dark: 0xFF151514)
static let pageBgFade = dynamic(light: 0x00FFFFFF, dark: 0x00151514)
static let ink = dynamic(light: 0xFF171717, dark: 0xFFF4F3EF)
@@ -23,17 +24,27 @@ enum MobileDesignColors {
static let accent = dynamic(light: 0xFF111111, dark: 0xFF5B5954)
static let fileLink = dynamic(light: 0xFF2563EB, dark: 0xFF60A5FA)
static let primaryAction = dynamic(light: 0xFF111111, dark: 0xFF454540)
- static let primaryActionText = dynamic(light: 0xFFFFFFFF, dark: 0xFFFFFFFF)
+ static let contentOnAction = dynamic(light: 0xFFFFFFFF, dark: 0xFFFFFFFF)
static let connectHeroBg = dynamic(light: 0xFFE6EDFF, dark: 0xFF2B2B29)
static let connectHeroAccent = dynamic(light: 0xFF9DB4FF, dark: 0xFF4A4944)
static let connectHeroSecondary = dynamic(light: 0xFFC9C5FF, dark: 0xFF3C3B38)
static let connectHeroSurface = dynamic(light: 0xFFF8FAFF, dark: 0xFF252522)
static let connectScanAccent = dynamic(light: 0xFFFFD021, dark: 0xFFFFD021)
- static let modalScrim = dynamic(light: 0x44000000, dark: 0x44000000)
+ static let scrim = dynamic(light: 0x44000000, dark: 0x44000000)
+ static let shellScrim = dynamic(light: 0x24000000, dark: 0x24000000)
+ static let mediaBackground = dynamic(light: 0xFF000000, dark: 0xFF000000)
+ static let mediaScrim = dynamic(light: 0xB8000000, dark: 0xB8000000)
+ static let mediaControlBackground = dynamic(light: 0x8C000000, dark: 0x8C000000)
+ static let toastBackground = dynamic(light: 0xD1171717, dark: 0xD1171717)
+ static let shadowFaint = dynamic(light: 0x08000000, dark: 0x08000000)
+ static let shadowSubtle = dynamic(light: 0x12000000, dark: 0x12000000)
+ static let shadowMedium = dynamic(light: 0x18000000, dark: 0x18000000)
+ static let shadowStrong = dynamic(light: 0x24000000, dark: 0x24000000)
+ static let floatingBorder = dynamic(light: 0x18000000, dark: 0x18000000)
static let soft = dynamic(light: 0xFFF4F3F0, dark: 0xFF2D2C28)
static let floatingPanelBg = dynamic(light: 0xFFF7F7F5, dark: 0xFF1E1E1C)
- static let green = dynamic(light: 0xFF27C46A, dark: 0xFF3BD47B)
- static let red = dynamic(light: 0xFFE04F4F, dark: 0xFFFF6B6B)
+ static let statusSuccess = dynamic(light: 0xFF27C46A, dark: 0xFF3BD47B)
+ static let statusDanger = dynamic(light: 0xFFE04F4F, dark: 0xFFFF6B6B)
static let codeLineNumber = dynamic(light: 0xFFAAA69D, dark: 0xFF77756E)
static let codeKeyword = dynamic(light: 0xFF8F3F71, dark: 0xFFD99AC4)
static let codeString = dynamic(light: 0xFF477A4A, dark: 0xFF9BCB9D)
diff --git a/src/apps/mobile/ios/BitFun/Features/Pairing/PairingSheet.swift b/src/apps/mobile/ios/BitFun/Features/Pairing/PairingSheet.swift
index 23b008f26c..1264ef27d5 100644
--- a/src/apps/mobile/ios/BitFun/Features/Pairing/PairingSheet.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Pairing/PairingSheet.swift
@@ -104,7 +104,7 @@ struct PairingSheet: View {
Text(model.localized("扫描二维码"))
.font(.system(size: 24, weight: .bold)).foregroundStyle(BitFunTheme.ink)
if let error = model.pairingError {
- Text(error).font(.system(size: 13)).foregroundStyle(BitFunTheme.red)
+ Text(error).font(.system(size: 13)).foregroundStyle(BitFunTheme.statusDanger)
.multilineTextAlignment(.center)
}
}
@@ -158,7 +158,7 @@ struct PairingSheet: View {
(!hints.requiresAccount || (!effectiveUserID.isEmpty && !pairingPassword.isEmpty))
return ZStack {
- MobileDesignColors.modalScrim
+ BitFunTheme.scrim
.ignoresSafeArea()
.onTapGesture {
if !model.pairingBusy {
@@ -210,7 +210,7 @@ struct PairingSheet: View {
.lineSpacing(3)
}
if let error = model.pairingError {
- Text(error).font(.system(size: 13)).foregroundStyle(BitFunTheme.red)
+ Text(error).font(.system(size: 13)).foregroundStyle(BitFunTheme.statusDanger)
}
HStack(spacing: 12) {
pairingButton("取消", primary: false) {
@@ -247,7 +247,7 @@ struct PairingSheet: View {
Button(action: action) {
Text(model.localized(title))
.font(.system(size: 19, weight: .bold))
- .foregroundStyle(primary ? Color.white : BitFunTheme.ink)
+ .foregroundStyle(primary ? BitFunTheme.contentOnAction : BitFunTheme.ink)
.frame(maxWidth: .infinity, minHeight: 58)
.background(primary ? BitFunTheme.accent : BitFunTheme.soft)
.clipShape(Capsule())
diff --git a/src/apps/mobile/ios/BitFun/Features/Remote/RemoteHomeViews.swift b/src/apps/mobile/ios/BitFun/Features/Remote/RemoteHomeViews.swift
index bc891e35e7..7c2b923621 100644
--- a/src/apps/mobile/ios/BitFun/Features/Remote/RemoteHomeViews.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Remote/RemoteHomeViews.swift
@@ -28,7 +28,7 @@ struct RemoteHomeView: View {
.padding(.horizontal, 20)
Button(model.localized("连接")) { model.connectRemote() }
.font(.system(size: 15, weight: .medium))
- .foregroundStyle(.white)
+ .foregroundStyle(BitFunTheme.contentOnAction)
.frame(width: 136, height: 44)
.background(BitFunTheme.accent)
.clipShape(Capsule())
@@ -74,7 +74,7 @@ struct RemoteConnectedHomeView: View {
.multilineTextAlignment(.center)
Button { model.remoteCreateOpen = true } label: {
Label(model.localized("新建远程会话"), systemImage: "plus")
- .font(MobileDesignTypography.labelMedium.font).foregroundStyle(.white)
+ .font(MobileDesignTypography.labelMedium.font).foregroundStyle(BitFunTheme.contentOnAction)
.frame(minWidth: 176, minHeight: 44).background(BitFunTheme.accent).clipShape(Capsule())
}
.buttonStyle(.plain)
@@ -104,7 +104,7 @@ struct ConnectionStatusBar: View {
let onRetry: () -> Void
var body: some View {
HStack(spacing: 8) {
- Circle().fill(phase == .reconnecting ? BitFunTheme.muted : BitFunTheme.red).frame(width: 8, height: 8)
+ Circle().fill(phase == .reconnecting ? BitFunTheme.muted : BitFunTheme.statusDanger).frame(width: 8, height: 8)
Text(MobileLocalization.text(phase == .reconnecting ? "正在恢复连接" : "连接不可用"))
.font(.system(size: 13, weight: .medium))
Text(
diff --git a/src/apps/mobile/ios/BitFun/Features/Shell/BitFunTheme.swift b/src/apps/mobile/ios/BitFun/Features/Shell/BitFunTheme.swift
index 79e5b3bce8..8220eb2c31 100644
--- a/src/apps/mobile/ios/BitFun/Features/Shell/BitFunTheme.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Shell/BitFunTheme.swift
@@ -3,14 +3,26 @@ import SwiftUI
enum BitFunTheme {
// Generated from the HarmonyOS baseline through the mobile design contract.
static let page = MobileDesignColors.pageBg
+ static let transparent = MobileDesignColors.transparent
static let card = MobileDesignColors.card
static let soft = MobileDesignColors.soft
static let ink = MobileDesignColors.ink
static let muted = MobileDesignColors.muted
static let line = MobileDesignColors.line
static let accent = MobileDesignColors.accent
- static let green = MobileDesignColors.green
- static let red = MobileDesignColors.red
+ static let contentOnAction = MobileDesignColors.contentOnAction
+ static let scrim = MobileDesignColors.scrim
+ static let shellScrim = MobileDesignColors.shellScrim
+ static let mediaBackground = MobileDesignColors.mediaBackground
+ static let mediaScrim = MobileDesignColors.mediaScrim
+ static let mediaControlBackground = MobileDesignColors.mediaControlBackground
+ static let toastBackground = MobileDesignColors.toastBackground
+ static let shadowSubtle = MobileDesignColors.shadowSubtle
+ static let shadowMedium = MobileDesignColors.shadowMedium
+ static let shadowStrong = MobileDesignColors.shadowStrong
+ static let floatingBorder = MobileDesignColors.floatingBorder
+ static let statusSuccess = MobileDesignColors.statusSuccess
+ static let statusDanger = MobileDesignColors.statusDanger
}
struct CircleControl: View {
@@ -28,7 +40,7 @@ struct CircleControl: View {
.background(BitFunTheme.card)
.overlay(Circle().stroke(BitFunTheme.line, lineWidth: 1))
.clipShape(Circle())
- .shadow(color: .black.opacity(0.07), radius: 8, y: 3)
+ .shadow(color: BitFunTheme.shadowMedium, radius: 8, y: 3)
}
.buttonStyle(.plain)
.accessibilityLabel(systemName)
diff --git a/src/apps/mobile/ios/BitFun/Features/Shell/MobileShellView.swift b/src/apps/mobile/ios/BitFun/Features/Shell/MobileShellView.swift
index c480fdd4ba..2c683b60c7 100644
--- a/src/apps/mobile/ios/BitFun/Features/Shell/MobileShellView.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Shell/MobileShellView.swift
@@ -17,7 +17,7 @@ struct MobileShellView: View {
if sessionActionsOpen, let anchor {
let frame = proxy[anchor]
ZStack(alignment: .topLeading) {
- Color.clear
+ BitFunTheme.transparent
.contentShape(Rectangle())
.onTapGesture { sessionActionsOpen = false }
ConversationActionsPopover(
@@ -45,7 +45,7 @@ struct MobileShellView: View {
let frame = proxy[anchor]
let remote = model.surface == .remote
ZStack(alignment: .topLeading) {
- Color.clear
+ BitFunTheme.transparent
.contentShape(Rectangle())
.onTapGesture { sidebarActionSession = nil }
SessionActionSurface(
@@ -83,10 +83,10 @@ struct MobileShellView: View {
if let message = model.toastMessage {
Text(message)
.font(.system(size: 13, weight: .medium))
- .foregroundStyle(Color.white)
+ .foregroundStyle(BitFunTheme.contentOnAction)
.padding(.horizontal, 16)
.frame(minHeight: 38)
- .background(Color.black.opacity(0.82))
+ .background(BitFunTheme.toastBackground)
.clipShape(Capsule())
.padding(.bottom, 86)
.transition(.move(edge: .bottom).combined(with: .opacity))
@@ -231,7 +231,7 @@ struct MobileShellView: View {
}
.clipShape(RoundedRectangle(cornerRadius: !sidebarVisible && model.drawerOpen ? 28 : 0))
.shadow(
- color: !sidebarVisible && model.drawerOpen ? .black.opacity(0.14) : .clear,
+ color: !sidebarVisible && model.drawerOpen ? BitFunTheme.shellScrim : BitFunTheme.transparent,
radius: !sidebarVisible && model.drawerOpen ? 34 : 0,
x: !sidebarVisible && model.drawerOpen ? -10 : 0
)
diff --git a/src/apps/mobile/ios/BitFun/Features/Shell/RemoteCreateSessionView.swift b/src/apps/mobile/ios/BitFun/Features/Shell/RemoteCreateSessionView.swift
index b957a76ed8..d638b0fd7e 100644
--- a/src/apps/mobile/ios/BitFun/Features/Shell/RemoteCreateSessionView.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Shell/RemoteCreateSessionView.swift
@@ -64,7 +64,7 @@ struct RemoteCreateSessionView: View {
let anchor = anchors[kind] {
let frame = proxy[anchor]
ZStack(alignment: .topLeading) {
- Color.clear
+ BitFunTheme.transparent
.contentShape(Rectangle())
.onTapGesture { pickerKind = nil }
selectionContent(kind: kind, includeHeader: false)
@@ -171,7 +171,7 @@ struct RemoteCreateSessionView: View {
"",
text: $instruction,
prompt: Text(model.localized(speech.isListening ? "正在聆听" : "告诉 BitFun 要做什么"))
- .foregroundColor(speech.isListening ? BitFunTheme.green : BitFunTheme.muted),
+ .foregroundColor(speech.isListening ? BitFunTheme.statusSuccess : BitFunTheme.muted),
axis: .vertical
)
.font(MobileDesignTypography.bodyLarge.font)
@@ -206,13 +206,13 @@ struct RemoteCreateSessionView: View {
Group {
if model.remoteCreateSubmitting {
ProgressView()
- .tint(Color.white)
+ .tint(BitFunTheme.contentOnAction)
} else {
Image(systemName: instruction.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
? (speech.isListening ? "stop.fill" : "mic.fill")
: "arrow.up")
.font(.system(size: 17, weight: .semibold))
- .foregroundStyle(canSubmit ? Color.white : BitFunTheme.ink)
+ .foregroundStyle(canSubmit ? BitFunTheme.contentOnAction : BitFunTheme.ink)
}
}
.frame(
@@ -235,7 +235,7 @@ struct RemoteCreateSessionView: View {
.frame(minHeight: MobileDesignGeometry.composerExpandedHeight)
.background(BitFunTheme.card)
.clipShape(RoundedRectangle(cornerRadius: MobileDesignGeometry.composerExpandedRadius))
- .shadow(color: .black.opacity(0.05), radius: 10, y: 2)
+ .shadow(color: BitFunTheme.shadowSubtle, radius: 10, y: 2)
.padding(.horizontal, MobileDesignGeometry.contentGutter)
.padding(.top, 8)
.padding(.bottom, 14)
@@ -249,7 +249,7 @@ struct RemoteCreateSessionView: View {
private func createStatus(message: String, retryTitle: String, action: @escaping () -> Void) -> some View {
HStack(alignment: .top, spacing: 8) {
Image(systemName: "exclamationmark.triangle")
- .foregroundStyle(BitFunTheme.red)
+ .foregroundStyle(BitFunTheme.statusDanger)
Text(message)
.font(.system(size: 13))
.foregroundStyle(BitFunTheme.ink)
@@ -410,7 +410,7 @@ struct RemoteCreateSessionView: View {
HStack(spacing: 12) {
Image(systemName: selected ? "checkmark.circle" : "circle")
.font(.system(size: 19))
- .foregroundStyle(selected ? BitFunTheme.ink : Color.clear)
+ .foregroundStyle(selected ? BitFunTheme.ink : BitFunTheme.transparent)
.frame(width: 20)
Image(systemName: icon)
.font(.system(size: 19, weight: .medium))
diff --git a/src/apps/mobile/ios/BitFun/Features/Shell/RemoteFilePreviewView.swift b/src/apps/mobile/ios/BitFun/Features/Shell/RemoteFilePreviewView.swift
index abf2a62a31..15b9924f7f 100644
--- a/src/apps/mobile/ios/BitFun/Features/Shell/RemoteFilePreviewView.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Shell/RemoteFilePreviewView.swift
@@ -148,10 +148,10 @@ struct RemoteFilePreviewSheet: View {
Image(systemName: "checkmark.circle")
} else if model.downloadPhase == .failed {
Image(systemName: "exclamationmark.triangle")
- .foregroundStyle(BitFunTheme.red)
+ .foregroundStyle(BitFunTheme.statusDanger)
}
Text(status).font(MobileDesignTypography.labelSmall.font)
- .foregroundStyle(model.downloadPhase == .failed ? BitFunTheme.red : BitFunTheme.muted)
+ .foregroundStyle(model.downloadPhase == .failed ? BitFunTheme.statusDanger : BitFunTheme.muted)
.lineLimit(2)
if model.downloadPhase == .failed {
Button(model.localized("重试")) { model.retryRemoteDownload() }
@@ -222,7 +222,7 @@ struct RemoteFilePreviewSheet: View {
MarkdownMessageView(text: block.text, model: model)
.id(block.startLine)
.background(GeometryReader { geometry in
- Color.clear.preference(
+ BitFunTheme.transparent.preference(
key: FilePreviewVisibleLinePreferenceKey.self,
value: {
let frame = geometry.frame(in: .named("file-preview-scroll"))
@@ -253,7 +253,7 @@ struct RemoteFilePreviewSheet: View {
.foregroundStyle(BitFunTheme.ink)
.frame(maxWidth: .infinity, alignment: .leading)
.background(GeometryReader { geometry in
- Color.clear.preference(
+ BitFunTheme.transparent.preference(
key: FilePreviewVisibleLinePreferenceKey.self,
value: {
let frame = geometry.frame(in: .named("file-preview-scroll"))
diff --git a/src/apps/mobile/ios/BitFun/Features/Shell/RemoteSettingsViews.swift b/src/apps/mobile/ios/BitFun/Features/Shell/RemoteSettingsViews.swift
index 65a8a00f7f..8f4db32e3c 100644
--- a/src/apps/mobile/ios/BitFun/Features/Shell/RemoteSettingsViews.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Shell/RemoteSettingsViews.swift
@@ -375,7 +375,7 @@ struct RemoteControlSettingsView: View {
if let failure = model.remotePermissionFailure, !failure.isEmpty {
Text(failure)
- .font(.system(size: 12)).foregroundStyle(BitFunTheme.red)
+ .font(.system(size: 12)).foregroundStyle(BitFunTheme.statusDanger)
.padding(.horizontal, 18).padding(.bottom, 10)
}
@@ -389,7 +389,7 @@ struct RemoteControlSettingsView: View {
private var fullAccessConfirmation: some View {
VStack(alignment: .leading, spacing: 10) {
Text(model.localized("确认完全访问"))
- .font(.system(size: 15, weight: .bold)).foregroundStyle(BitFunTheme.red)
+ .font(.system(size: 15, weight: .bold)).foregroundStyle(BitFunTheme.statusDanger)
Text(model.localized("完全访问会取消所有操作确认。仅在你信任当前桌面端时启用。"))
.font(.system(size: 13)).foregroundStyle(BitFunTheme.ink).lineSpacing(4)
HStack(spacing: 10) {
@@ -401,7 +401,7 @@ struct RemoteControlSettingsView: View {
}
}
.padding(16)
- .overlay(RoundedRectangle(cornerRadius: 18).stroke(BitFunTheme.red, lineWidth: 1))
+ .overlay(RoundedRectangle(cornerRadius: 18).stroke(BitFunTheme.statusDanger, lineWidth: 1))
.padding(.horizontal, 12).padding(.bottom, 14)
}
@@ -465,9 +465,9 @@ struct RemoteControlSettingsView: View {
Button(action: action) {
Text(model.localized(title))
.font(.system(size: 14, weight: .medium))
- .foregroundStyle(destructive ? Color.white : BitFunTheme.ink)
+ .foregroundStyle(destructive ? BitFunTheme.contentOnAction : BitFunTheme.ink)
.frame(maxWidth: .infinity, minHeight: 42)
- .background(destructive ? BitFunTheme.red : BitFunTheme.soft)
+ .background(destructive ? BitFunTheme.statusDanger : BitFunTheme.soft)
.clipShape(Capsule())
}
.buttonStyle(.plain)
@@ -652,7 +652,7 @@ struct GeneralChatConfigSheet: View {
} label: {
HStack(spacing: 10) {
Image(systemName: option.selected ? "checkmark.circle" : "circle")
- .foregroundStyle(option.selected ? BitFunTheme.ink : Color.clear)
+ .foregroundStyle(option.selected ? BitFunTheme.ink : BitFunTheme.transparent)
.frame(width: 20, height: 20)
VStack(alignment: .leading, spacing: 2) {
Text(option.primaryLabel)
@@ -667,7 +667,7 @@ struct GeneralChatConfigSheet: View {
}
.padding(.horizontal, 10)
.frame(height: MobileDesignGeometry.modelAccountRowHeight)
- .background(option.selected ? BitFunTheme.soft : Color.clear)
+ .background(option.selected ? BitFunTheme.soft : BitFunTheme.transparent)
.clipShape(RoundedRectangle(cornerRadius: 9))
}
.buttonStyle(.plain)
@@ -698,7 +698,7 @@ struct GeneralChatConfigSheet: View {
} label: {
Text(model.localized(clearAPIKey ? "保留已保存的 Key" : "清除已保存的 API Key"))
.font(MobileDesignTypography.bodySmall.font)
- .foregroundStyle(clearAPIKey ? BitFunTheme.ink : BitFunTheme.red)
+ .foregroundStyle(clearAPIKey ? BitFunTheme.ink : BitFunTheme.statusDanger)
}
.buttonStyle(.plain)
}
@@ -723,11 +723,11 @@ struct GeneralChatConfigSheet: View {
}
if let failure = model.generalConfigFailure {
Text(configFailureText(failure))
- .font(MobileDesignTypography.bodySmall.font).foregroundStyle(BitFunTheme.red)
+ .font(MobileDesignTypography.bodySmall.font).foregroundStyle(BitFunTheme.statusDanger)
}
if let message = model.generalConnectionTestMessage {
Text(message).font(MobileDesignTypography.bodySmall.font)
- .foregroundStyle(message == model.localized("连接成功") ? BitFunTheme.green : BitFunTheme.red)
+ .foregroundStyle(message == model.localized("连接成功") ? BitFunTheme.statusSuccess : BitFunTheme.statusDanger)
}
}
.padding(.horizontal, 16)
@@ -806,7 +806,7 @@ struct GeneralChatConfigSheet: View {
Button(action: action) {
Text(model.localized(title))
.font(MobileDesignTypography.bodyLarge.font.weight(.medium))
- .foregroundStyle(primary ? Color.white : BitFunTheme.ink)
+ .foregroundStyle(primary ? BitFunTheme.contentOnAction : BitFunTheme.ink)
.frame(maxWidth: .infinity, minHeight: 50)
.background(primary ? BitFunTheme.accent : BitFunTheme.soft)
.clipShape(Capsule())
diff --git a/src/apps/mobile/ios/BitFun/Features/Shell/SessionActionComponents.swift b/src/apps/mobile/ios/BitFun/Features/Shell/SessionActionComponents.swift
index a65122e5e1..942c0beda5 100644
--- a/src/apps/mobile/ios/BitFun/Features/Shell/SessionActionComponents.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Shell/SessionActionComponents.swift
@@ -75,7 +75,7 @@ struct SessionActionSurface: View {
.stroke(BitFunTheme.line, lineWidth: 1)
)
.shadow(
- color: presentation == .popover ? BitFunTheme.line : .clear,
+ color: presentation == .popover ? BitFunTheme.line : BitFunTheme.transparent,
radius: presentation == .popover ? 20 : 0,
y: presentation == .popover ? 8 : 0
)
@@ -132,8 +132,8 @@ struct SessionActionSurface: View {
}
confirmationButton(
"删除",
- fill: BitFunTheme.red,
- foreground: .white,
+ fill: BitFunTheme.statusDanger,
+ foreground: BitFunTheme.contentOnAction,
emphasized: true
) {
onDelete()
@@ -153,11 +153,11 @@ struct SessionActionSurface: View {
HStack(spacing: 12) {
Image(systemName: icon)
.font(.system(size: 19, weight: .regular))
- .foregroundStyle(destructive ? BitFunTheme.red : BitFunTheme.muted)
+ .foregroundStyle(destructive ? BitFunTheme.statusDanger : BitFunTheme.muted)
.frame(width: 23, height: 23)
Text(model.localized(title))
.font(.system(size: 15))
- .foregroundStyle(destructive ? BitFunTheme.red : BitFunTheme.ink)
+ .foregroundStyle(destructive ? BitFunTheme.statusDanger : BitFunTheme.ink)
Spacer(minLength: 0)
}
.padding(.horizontal, 10)
diff --git a/src/apps/mobile/ios/BitFun/Features/Shell/SidebarView.swift b/src/apps/mobile/ios/BitFun/Features/Shell/SidebarView.swift
index 8dbeef7b1d..a5df9c31bd 100644
--- a/src/apps/mobile/ios/BitFun/Features/Shell/SidebarView.swift
+++ b/src/apps/mobile/ios/BitFun/Features/Shell/SidebarView.swift
@@ -127,7 +127,7 @@ struct SidebarView: View {
let frame = proxy[anchor]
let menuHeight = MobileDesignGeometry.compactPopoverActionHeight * 2 + 16
ZStack(alignment: .topLeading) {
- Color.clear
+ BitFunTheme.transparent
.contentShape(Rectangle())
.onTapGesture { workspaceCreatePath = nil }
workspaceCreateMenu(workspace)
@@ -199,7 +199,7 @@ struct SidebarView: View {
.background(BitFunTheme.card)
.overlay(Circle().stroke(BitFunTheme.line, lineWidth: 1))
.clipShape(Circle())
- .shadow(color: .black.opacity(0.08), radius: 10, y: 4)
+ .shadow(color: BitFunTheme.shadowMedium, radius: 10, y: 4)
}
.buttonStyle(.plain)
.accessibilityLabel(Text(model.localized("搜索")))
@@ -368,8 +368,8 @@ struct SidebarView: View {
Text(device.name).font(.system(size: 15, weight: current ? .medium : .regular))
.foregroundStyle(BitFunTheme.ink).lineLimit(1)
Spacer(minLength: 0)
- Circle().fill(device.online ? BitFunTheme.green : BitFunTheme.muted).frame(width: 7, height: 7)
- if current { Text(model.localized("当前控制")).font(.system(size: 11)).foregroundStyle(BitFunTheme.green) }
+ Circle().fill(device.online ? BitFunTheme.statusSuccess : BitFunTheme.muted).frame(width: 7, height: 7)
+ if current { Text(model.localized("当前控制")).font(.system(size: 11)).foregroundStyle(BitFunTheme.statusSuccess) }
if device.status == "LOADING" { ProgressView().controlSize(.small) }
Image(systemName: device.expanded ? "chevron.down" : "chevron.right")
.font(.system(size: 12, weight: .medium)).foregroundStyle(BitFunTheme.muted)
@@ -391,7 +391,7 @@ struct SidebarView: View {
.padding(.horizontal, 18).frame(height: 42)
} else if device.status == "FAILED" {
Button { model.retryDeviceDirectory(device) } label: {
- Text(model.localized("工作区加载失败,点按重试")).font(.system(size: 13)).foregroundStyle(BitFunTheme.red)
+ Text(model.localized("工作区加载失败,点按重试")).font(.system(size: 13)).foregroundStyle(BitFunTheme.statusDanger)
.frame(maxWidth: .infinity, minHeight: 42, alignment: .leading).padding(.leading, 18)
}.buttonStyle(.plain)
} else if device.status == "READY" && device.online && device.workspaces.isEmpty && device.sessions.isEmpty {
@@ -459,7 +459,7 @@ struct SidebarView: View {
Button { model.retryRemoteWorkspaces() } label: {
Text(model.localized("工作区加载失败,点按重试"))
.font(.system(size: 13))
- .foregroundStyle(BitFunTheme.red)
+ .foregroundStyle(BitFunTheme.statusDanger)
.frame(maxWidth: .infinity, minHeight: 42, alignment: .leading)
.padding(.horizontal, 10)
}
@@ -723,7 +723,7 @@ struct SidebarView: View {
.foregroundStyle(BitFunTheme.ink)
.lineLimit(1)
Spacer(minLength: 0)
- Circle().fill(BitFunTheme.green).frame(width: 7, height: 7)
+ Circle().fill(BitFunTheme.statusSuccess).frame(width: 7, height: 7)
ReferenceImage(assetName: "SidebarDownGlyph", width: 14, height: 14)
}
.padding(.horizontal, 10)
@@ -787,7 +787,7 @@ struct SidebarView: View {
.background(BitFunTheme.card)
.overlay(RoundedRectangle(cornerRadius: 23).stroke(BitFunTheme.line, lineWidth: 1))
.clipShape(Capsule())
- .shadow(color: .black.opacity(0.08), radius: 10, y: 4)
+ .shadow(color: BitFunTheme.shadowMedium, radius: 10, y: 4)
}
.buttonStyle(.plain)
Spacer(minLength: 0)
@@ -796,7 +796,7 @@ struct SidebarView: View {
.frame(width: 46, height: 46)
.background(BitFunTheme.card)
.clipShape(Circle())
- .shadow(color: .black.opacity(0.08), radius: 10, y: 4)
+ .shadow(color: BitFunTheme.shadowMedium, radius: 10, y: 4)
}
.buttonStyle(.plain)
.accessibilityLabel(Text(model.localized("设置")))
@@ -861,7 +861,7 @@ private struct SidebarRecentRow: View {
.padding(.leading, 12)
.padding(.trailing, 4)
.frame(minHeight: metadata == nil ? 44 : 56)
- .background(selected ? BitFunTheme.soft : .clear)
+ .background(selected ? BitFunTheme.soft : BitFunTheme.transparent)
.clipShape(RoundedRectangle(cornerRadius: 10))
}
}
@@ -939,7 +939,7 @@ private struct SidebarWorkspaceRow: View {
}
.padding(.horizontal, 10)
.frame(height: 46)
- .background(workspace.selected ? BitFunTheme.soft.opacity(0.75) : Color.clear)
+ .background(workspace.selected ? BitFunTheme.soft.opacity(0.75) : BitFunTheme.transparent)
.clipShape(RoundedRectangle(cornerRadius: 10))
if expanded {
@@ -955,7 +955,7 @@ private struct SidebarWorkspaceRow: View {
Button { onOpenSession(session) } label: {
HStack(spacing: 10) {
if ["running", "active", "in_progress"].contains(session.status.lowercased()) {
- Circle().fill(BitFunTheme.green).frame(width: 7, height: 7)
+ Circle().fill(BitFunTheme.statusSuccess).frame(width: 7, height: 7)
}
Image(systemName: "doc")
.font(.system(size: 18, weight: .regular))
@@ -999,7 +999,7 @@ private struct SidebarWorkspaceRow: View {
.padding(.leading, 32)
.padding(.trailing, 4)
.frame(minHeight: metadata(session) == nil ? 44 : 56)
- .background(isSelected(session) ? BitFunTheme.soft : Color.clear)
+ .background(isSelected(session) ? BitFunTheme.soft : BitFunTheme.transparent)
.clipShape(RoundedRectangle(cornerRadius: 9))
}
if workspace.sessions.count > sessionLimit {
diff --git a/src/apps/mobile/ios/BitFun/Infrastructure/Platform/QRCodeScannerView.swift b/src/apps/mobile/ios/BitFun/Infrastructure/Platform/QRCodeScannerView.swift
index 60345439c4..f61ebe92a8 100644
--- a/src/apps/mobile/ios/BitFun/Infrastructure/Platform/QRCodeScannerView.swift
+++ b/src/apps/mobile/ios/BitFun/Infrastructure/Platform/QRCodeScannerView.swift
@@ -21,11 +21,11 @@ final class QRScannerController: UIViewController, AVCaptureMetadataOutputObject
override func viewDidLoad() {
super.viewDidLoad()
- view.backgroundColor = .black
+ view.backgroundColor = UIColor(BitFunTheme.mediaBackground)
let close = UIButton(type: .system)
close.setImage(UIImage(systemName: "xmark"), for: .normal)
- close.tintColor = .white
- close.backgroundColor = UIColor.black.withAlphaComponent(0.55)
+ close.tintColor = UIColor(BitFunTheme.contentOnAction)
+ close.backgroundColor = UIColor(BitFunTheme.mediaControlBackground)
close.layer.cornerRadius = 22
close.addAction(UIAction { [weak self] _ in self?.dismiss(animated: true) }, for: .touchUpInside)
close.translatesAutoresizingMaskIntoConstraints = false
diff --git a/src/apps/relay-server/static/assets/ChatPage-DseABuXP.js b/src/apps/relay-server/static/assets/ChatPage-B79eLrUh.js
similarity index 86%
rename from src/apps/relay-server/static/assets/ChatPage-DseABuXP.js
rename to src/apps/relay-server/static/assets/ChatPage-B79eLrUh.js
index e79b0c3e49..a08651e3e7 100644
--- a/src/apps/relay-server/static/assets/ChatPage-DseABuXP.js
+++ b/src/apps/relay-server/static/assets/ChatPage-B79eLrUh.js
@@ -1,18 +1,18 @@
-import{g as me,j as h,R as it,c as mn,u as Ye,a as Ft,b as Zo,r as N,d as Gs,e as on,S as Zs,_ as Xs,i as Ks,m as Ys}from"./index-BNRAmblM.js";function Qs(e,t){const n={};return(e[e.length-1]===""?[...e,""]:e).join((n.padRight?" ":"")+","+(n.padLeft===!1?"":" ")).trim()}const Js=/^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,eu=/^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,tu={};function Zi(e,t){return(tu.jsx?eu:Js).test(e)}const nu=/[ \t\n\f\r]/g;function ru(e){return typeof e=="object"?e.type==="text"?Xi(e.value):!1:Xi(e)}function Xi(e){return e.replace(nu,"")===""}class Yt{constructor(t,n,r){this.normal=n,this.property=t,r&&(this.space=r)}}Yt.prototype.normal={};Yt.prototype.property={};Yt.prototype.space=void 0;function Xo(e,t){const n={},r={};for(const i of e)Object.assign(n,i.property),Object.assign(r,i.normal);return new Yt(n,r,t)}function ri(e){return e.toLowerCase()}class Be{constructor(t,n){this.attribute=n,this.property=t}}Be.prototype.attribute="";Be.prototype.booleanish=!1;Be.prototype.boolean=!1;Be.prototype.commaOrSpaceSeparated=!1;Be.prototype.commaSeparated=!1;Be.prototype.defined=!1;Be.prototype.mustUseProperty=!1;Be.prototype.number=!1;Be.prototype.overloadedBoolean=!1;Be.prototype.property="";Be.prototype.spaceSeparated=!1;Be.prototype.space=void 0;let iu=0;const Q=vt(),Ee=vt(),ii=vt(),F=vt(),ge=vt(),Lt=vt(),We=vt();function vt(){return 2**++iu}const ai=Object.freeze(Object.defineProperty({__proto__:null,boolean:Q,booleanish:Ee,commaOrSpaceSeparated:We,commaSeparated:Lt,number:F,overloadedBoolean:ii,spaceSeparated:ge},Symbol.toStringTag,{value:"Module"})),Mn=Object.keys(ai);class wi extends Be{constructor(t,n,r,i){let o=-1;if(super(t,n),Ki(this,"space",i),typeof r=="number")for(;++o4&&n.slice(0,4)==="data"&&uu.test(t)){if(t.charAt(4)==="-"){const o=t.slice(5).replace(Yi,du);r="data"+o.charAt(0).toUpperCase()+o.slice(1)}else{const o=t.slice(4);if(!Yi.test(o)){let a=o.replace(su,pu);a.charAt(0)!=="-"&&(a="-"+a),t="data"+a}}i=wi}return new i(r,t)}function pu(e){return"-"+e.toLowerCase()}function du(e){return e.charAt(1).toUpperCase()}const fu=Xo([Ko,au,Jo,el,tl],"html"),Si=Xo([Ko,ou,Jo,el,tl],"svg");function hu(e){return e.join(" ").trim()}var Et={},Fn,Qi;function gu(){if(Qi)return Fn;Qi=1;var e=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,t=/\n/g,n=/^\s*/,r=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,i=/^:\s*/,o=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,a=/^[;\s]*/,l=/^\s+|\s+$/g,s=`
-`,u="/",p="*",c="",f="comment",d="declaration";function g(S,x){if(typeof S!="string")throw new TypeError("First argument must be a string");if(!S)return[];x=x||{};var v=1,y=1;function _(P){var z=P.match(t);z&&(v+=z.length);var G=P.lastIndexOf(s);y=~G?P.length-G:y+P.length}function C(){var P={line:v,column:y};return function(z){return z.position=new m(P),A(),z}}function m(P){this.start=P,this.end={line:v,column:y},this.source=x.source}m.prototype.content=S;function T(P){var z=new Error(x.source+":"+v+":"+y+": "+P);if(z.reason=P,z.filename=x.source,z.line=v,z.column=y,z.source=S,!x.silent)throw z}function j(P){var z=P.exec(S);if(z){var G=z[0];return _(G),S=S.slice(G.length),z}}function A(){j(n)}function E(P){var z;for(P=P||[];z=R();)z!==!1&&P.push(z);return P}function R(){var P=C();if(!(u!=S.charAt(0)||p!=S.charAt(1))){for(var z=2;c!=S.charAt(z)&&(p!=S.charAt(z)||u!=S.charAt(z+1));)++z;if(z+=2,c===S.charAt(z-1))return T("End of comment missing");var G=S.slice(2,z-2);return y+=2,_(G),S=S.slice(z),y+=2,P({type:f,comment:G})}}function M(){var P=C(),z=j(r);if(z){if(R(),!j(i))return T("property missing ':'");var G=j(o),J=P({type:d,property:k(z[0].replace(e,c)),value:G?k(G[0].replace(e,c)):c});return j(a),J}}function H(){var P=[];E(P);for(var z;z=M();)z!==!1&&(P.push(z),E(P));return P}return A(),H()}function k(S){return S?S.replace(l,c):c}return Fn=g,Fn}var Ji;function mu(){if(Ji)return Et;Ji=1;var e=Et&&Et.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};Object.defineProperty(Et,"__esModule",{value:!0}),Et.default=n;const t=e(gu());function n(r,i){let o=null;if(!r||typeof r!="string")return o;const a=(0,t.default)(r),l=typeof i=="function";return a.forEach(s=>{if(s.type!=="declaration")return;const{property:u,value:p}=s;l?i(u,p,s):p&&(o=o||{},o[u]=p)}),o}return Et}var zt={},ea;function yu(){if(ea)return zt;ea=1,Object.defineProperty(zt,"__esModule",{value:!0}),zt.camelCase=void 0;var e=/^--[a-zA-Z0-9_-]+$/,t=/-([a-z])/g,n=/^[^-]+$/,r=/^-(webkit|moz|ms|o|khtml)-/,i=/^-(ms)-/,o=function(u){return!u||n.test(u)||e.test(u)},a=function(u,p){return p.toUpperCase()},l=function(u,p){return"".concat(p,"-")},s=function(u,p){return p===void 0&&(p={}),o(u)?u:(u=u.toLowerCase(),p.reactCompat?u=u.replace(i,l):u=u.replace(r,l),u.replace(t,a))};return zt.camelCase=s,zt}var Pt,ta;function bu(){if(ta)return Pt;ta=1;var e=Pt&&Pt.__importDefault||function(i){return i&&i.__esModule?i:{default:i}},t=e(mu()),n=yu();function r(i,o){var a={};return!i||typeof i!="string"||(0,t.default)(i,function(l,s){l&&s&&(a[(0,n.camelCase)(l,o)]=s)}),a}return r.default=r,Pt=r,Pt}var xu=bu();const ku=me(xu),nl=rl("end"),_i=rl("start");function rl(e){return t;function t(n){const r=n&&n.position&&n.position[e]||{};if(typeof r.line=="number"&&r.line>0&&typeof r.column=="number"&&r.column>0)return{line:r.line,column:r.column,offset:typeof r.offset=="number"&&r.offset>-1?r.offset:void 0}}}function vu(e){const t=_i(e),n=nl(e);if(t&&n)return{start:t,end:n}}function qt(e){return!e||typeof e!="object"?"":"position"in e||"type"in e?na(e.position):"start"in e||"end"in e?na(e):"line"in e||"column"in e?oi(e):""}function oi(e){return ra(e&&e.line)+":"+ra(e&&e.column)}function na(e){return oi(e&&e.start)+"-"+oi(e&&e.end)}function ra(e){return e&&typeof e=="number"?e:1}class Oe extends Error{constructor(t,n,r){super(),typeof n=="string"&&(r=n,n=void 0);let i="",o={},a=!1;if(n&&("line"in n&&"column"in n?o={place:n}:"start"in n&&"end"in n?o={place:n}:"type"in n?o={ancestors:[n],place:n.position}:o={...n}),typeof t=="string"?i=t:!o.cause&&t&&(a=!0,i=t.message,o.cause=t),!o.ruleId&&!o.source&&typeof r=="string"){const s=r.indexOf(":");s===-1?o.ruleId=r:(o.source=r.slice(0,s),o.ruleId=r.slice(s+1))}if(!o.place&&o.ancestors&&o.ancestors){const s=o.ancestors[o.ancestors.length-1];s&&(o.place=s.position)}const l=o.place&&"start"in o.place?o.place.start:o.place;this.ancestors=o.ancestors||void 0,this.cause=o.cause||void 0,this.column=l?l.column:void 0,this.fatal=void 0,this.file="",this.message=i,this.line=l?l.line:void 0,this.name=qt(o.place)||"1:1",this.place=o.place||void 0,this.reason=this.message,this.ruleId=o.ruleId||void 0,this.source=o.source||void 0,this.stack=a&&o.cause&&typeof o.cause.stack=="string"?o.cause.stack:"",this.actual=void 0,this.expected=void 0,this.note=void 0,this.url=void 0}}Oe.prototype.file="";Oe.prototype.name="";Oe.prototype.reason="";Oe.prototype.message="";Oe.prototype.stack="";Oe.prototype.column=void 0;Oe.prototype.line=void 0;Oe.prototype.ancestors=void 0;Oe.prototype.cause=void 0;Oe.prototype.fatal=void 0;Oe.prototype.place=void 0;Oe.prototype.ruleId=void 0;Oe.prototype.source=void 0;const Ei={}.hasOwnProperty,wu=new Map,Su=/[A-Z]/g,_u=new Set(["table","tbody","thead","tfoot","tr"]),Eu=new Set(["td","th"]),il="https://github.com/syntax-tree/hast-util-to-jsx-runtime";function Cu(e,t){if(!t||t.Fragment===void 0)throw new TypeError("Expected `Fragment` in options");const n=t.filePath||void 0;let r;if(t.development){if(typeof t.jsxDEV!="function")throw new TypeError("Expected `jsxDEV` in options when `development: true`");r=Ou(n,t.jsxDEV)}else{if(typeof t.jsx!="function")throw new TypeError("Expected `jsx` in production options");if(typeof t.jsxs!="function")throw new TypeError("Expected `jsxs` in production options");r=Ru(n,t.jsx,t.jsxs)}const i={Fragment:t.Fragment,ancestors:[],components:t.components||{},create:r,elementAttributeNameCase:t.elementAttributeNameCase||"react",evaluater:t.createEvaluater?t.createEvaluater():void 0,filePath:n,ignoreInvalidStyle:t.ignoreInvalidStyle||!1,passKeys:t.passKeys!==!1,passNode:t.passNode||!1,schema:t.space==="svg"?Si:fu,stylePropertyNameCase:t.stylePropertyNameCase||"dom",tableCellAlignToStyle:t.tableCellAlignToStyle!==!1},o=al(i,e,void 0);return o&&typeof o!="string"?o:i.create(e,i.Fragment,{children:o||void 0},void 0)}function al(e,t,n){if(t.type==="element")return Tu(e,t,n);if(t.type==="mdxFlowExpression"||t.type==="mdxTextExpression")return Au(e,t);if(t.type==="mdxJsxFlowElement"||t.type==="mdxJsxTextElement")return Nu(e,t,n);if(t.type==="mdxjsEsm")return Lu(e,t);if(t.type==="root")return Iu(e,t,n);if(t.type==="text")return ju(e,t)}function Tu(e,t,n){const r=e.schema;let i=r;t.tagName.toLowerCase()==="svg"&&r.space==="html"&&(i=Si,e.schema=i),e.ancestors.push(t);const o=ll(e,t.tagName,!1),a=Du(e,t);let l=Ti(e,t);return _u.has(t.tagName)&&(l=l.filter(function(s){return typeof s=="string"?!ru(s):!0})),ol(e,a,o,t),Ci(a,l),e.ancestors.pop(),e.schema=r,e.create(t,o,a,n)}function Au(e,t){if(t.data&&t.data.estree&&e.evaluater){const r=t.data.estree.body[0];return r.type,e.evaluater.evaluateExpression(r.expression)}Gt(e,t.position)}function Lu(e,t){if(t.data&&t.data.estree&&e.evaluater)return e.evaluater.evaluateProgram(t.data.estree);Gt(e,t.position)}function Nu(e,t,n){const r=e.schema;let i=r;t.name==="svg"&&r.space==="html"&&(i=Si,e.schema=i),e.ancestors.push(t);const o=t.name===null?e.Fragment:ll(e,t.name,!0),a=Mu(e,t),l=Ti(e,t);return ol(e,a,o,t),Ci(a,l),e.ancestors.pop(),e.schema=r,e.create(t,o,a,n)}function Iu(e,t,n){const r={};return Ci(r,Ti(e,t)),e.create(t,e.Fragment,r,n)}function ju(e,t){return t.value}function ol(e,t,n,r){typeof n!="string"&&n!==e.Fragment&&e.passNode&&(t.node=r)}function Ci(e,t){if(t.length>0){const n=t.length>1?t:t[0];n&&(e.children=n)}}function Ru(e,t,n){return r;function r(i,o,a,l){const u=Array.isArray(a.children)?n:t;return l?u(o,a,l):u(o,a)}}function Ou(e,t){return n;function n(r,i,o,a){const l=Array.isArray(o.children),s=_i(r);return t(i,o,a,l,{columnNumber:s?s.column-1:void 0,fileName:e,lineNumber:s?s.line:void 0},void 0)}}function Du(e,t){const n={};let r,i;for(i in t.properties)if(i!=="children"&&Ei.call(t.properties,i)){const o=Fu(e,i,t.properties[i]);if(o){const[a,l]=o;e.tableCellAlignToStyle&&a==="align"&&typeof l=="string"&&Eu.has(t.tagName)?r=l:n[a]=l}}if(r){const o=n.style||(n.style={});o[e.stylePropertyNameCase==="css"?"text-align":"textAlign"]=r}return n}function Mu(e,t){const n={};for(const r of t.attributes)if(r.type==="mdxJsxExpressionAttribute")if(r.data&&r.data.estree&&e.evaluater){const o=r.data.estree.body[0];o.type;const a=o.expression;a.type;const l=a.properties[0];l.type,Object.assign(n,e.evaluater.evaluateExpression(l.argument))}else Gt(e,t.position);else{const i=r.name;let o;if(r.value&&typeof r.value=="object")if(r.value.data&&r.value.data.estree&&e.evaluater){const l=r.value.data.estree.body[0];l.type,o=e.evaluater.evaluateExpression(l.expression)}else Gt(e,t.position);else o=r.value===null?!0:r.value;n[i]=o}return n}function Ti(e,t){const n=[];let r=-1;const i=e.passKeys?new Map:wu;for(;++ri?0:i+t:t=t>i?i:t,n=n>0?n:0,r.length<1e4)a=Array.from(r),a.unshift(t,n),e.splice(...a);else for(n&&e.splice(t,n);o0?(Ve(e,e.length,0,t),e):t}const oa={}.hasOwnProperty;function ul(e){const t={};let n=-1;for(;++n13&&n<32||n>126&&n<160||n>55295&&n<57344||n>64975&&n<65008||(n&65535)===65535||(n&65535)===65534||n>1114111?"�":String.fromCodePoint(n)}function Ke(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const De=pt(/[A-Za-z]/),Re=pt(/[\dA-Za-z]/),Vu=pt(/[#-'*+\--9=?A-Z^-~]/);function yn(e){return e!==null&&(e<32||e===127)}const li=pt(/\d/),Gu=pt(/[\dA-Fa-f]/),Zu=pt(/[!-/:-@[-`{-~]/);function W(e){return e!==null&&e<-2}function he(e){return e!==null&&(e<0||e===32)}function ne(e){return e===-2||e===-1||e===32}const En=pt(new RegExp("\\p{P}|\\p{S}","u")),kt=pt(/\s/);function pt(e){return t;function t(n){return n!==null&&n>-1&&e.test(String.fromCharCode(n))}}function Ot(e){const t=[];let n=-1,r=0,i=0;for(;++n55295&&o<57344){const l=e.charCodeAt(n+1);o<56320&&l>56319&&l<57344?(a=String.fromCharCode(o,l),i=1):a="�"}else a=String.fromCharCode(o);a&&(t.push(e.slice(r,n),encodeURIComponent(a)),r=n+i+1,a=""),i&&(n+=i,i=0)}return t.join("")+e.slice(r)}function oe(e,t,n,r){const i=r?r-1:Number.POSITIVE_INFINITY;let o=0;return a;function a(s){return ne(s)?(e.enter(n),l(s)):t(s)}function l(s){return ne(s)&&o++a))return;const T=t.events.length;let j=T,A,E;for(;j--;)if(t.events[j][0]==="exit"&&t.events[j][1].type==="chunkFlow"){if(A){E=t.events[j][1].end;break}A=!0}for(x(r),m=T;my;){const C=n[_];t.containerState=C[1],C[0].exit.call(t,e)}n.length=y}function v(){i.write([null]),o=void 0,i=void 0,t.containerState._closeFlow=void 0}}function Ju(e,t,n){return oe(e,e.attempt(this.parser.constructs.document,t,n),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}function jt(e){if(e===null||he(e)||kt(e))return 1;if(En(e))return 2}function Cn(e,t,n){const r=[];let i=-1;for(;++i1&&e[n][1].end.offset-e[n][1].start.offset>1?2:1;const c={...e[r][1].end},f={...e[n][1].start};sa(c,-s),sa(f,s),a={type:s>1?"strongSequence":"emphasisSequence",start:c,end:{...e[r][1].end}},l={type:s>1?"strongSequence":"emphasisSequence",start:{...e[n][1].start},end:f},o={type:s>1?"strongText":"emphasisText",start:{...e[r][1].end},end:{...e[n][1].start}},i={type:s>1?"strong":"emphasis",start:{...a.start},end:{...l.end}},e[r][1].end={...a.start},e[n][1].start={...l.end},u=[],e[r][1].end.offset-e[r][1].start.offset&&(u=Ge(u,[["enter",e[r][1],t],["exit",e[r][1],t]])),u=Ge(u,[["enter",i,t],["enter",a,t],["exit",a,t],["enter",o,t]]),u=Ge(u,Cn(t.parser.constructs.insideSpan.null,e.slice(r+1,n),t)),u=Ge(u,[["exit",o,t],["enter",l,t],["exit",l,t],["exit",i,t]]),e[n][1].end.offset-e[n][1].start.offset?(p=2,u=Ge(u,[["enter",e[n][1],t],["exit",e[n][1],t]])):p=0,Ve(e,r-1,n-r+3,u),n=r+u.length-p-2;break}}for(n=-1;++n0&&ne(m)?oe(e,v,"linePrefix",o+1)(m):v(m)}function v(m){return m===null||W(m)?e.check(ua,k,_)(m):(e.enter("codeFlowValue"),y(m))}function y(m){return m===null||W(m)?(e.exit("codeFlowValue"),v(m)):(e.consume(m),y)}function _(m){return e.exit("codeFenced"),t(m)}function C(m,T,j){let A=0;return E;function E(z){return m.enter("lineEnding"),m.consume(z),m.exit("lineEnding"),R}function R(z){return m.enter("codeFencedFence"),ne(z)?oe(m,M,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(z):M(z)}function M(z){return z===l?(m.enter("codeFencedFenceSequence"),H(z)):j(z)}function H(z){return z===l?(A++,m.consume(z),H):A>=a?(m.exit("codeFencedFenceSequence"),ne(z)?oe(m,P,"whitespace")(z):P(z)):j(z)}function P(z){return z===null||W(z)?(m.exit("codeFencedFence"),T(z)):j(z)}}}function pc(e,t,n){const r=this;return i;function i(a){return a===null?n(a):(e.enter("lineEnding"),e.consume(a),e.exit("lineEnding"),o)}function o(a){return r.parser.lazy[r.now().line]?n(a):t(a)}}const Pn={name:"codeIndented",tokenize:fc},dc={partial:!0,tokenize:hc};function fc(e,t,n){const r=this;return i;function i(u){return e.enter("codeIndented"),oe(e,o,"linePrefix",5)(u)}function o(u){const p=r.events[r.events.length-1];return p&&p[1].type==="linePrefix"&&p[2].sliceSerialize(p[1],!0).length>=4?a(u):n(u)}function a(u){return u===null?s(u):W(u)?e.attempt(dc,a,s)(u):(e.enter("codeFlowValue"),l(u))}function l(u){return u===null||W(u)?(e.exit("codeFlowValue"),a(u)):(e.consume(u),l)}function s(u){return e.exit("codeIndented"),t(u)}}function hc(e,t,n){const r=this;return i;function i(a){return r.parser.lazy[r.now().line]?n(a):W(a)?(e.enter("lineEnding"),e.consume(a),e.exit("lineEnding"),i):oe(e,o,"linePrefix",5)(a)}function o(a){const l=r.events[r.events.length-1];return l&&l[1].type==="linePrefix"&&l[2].sliceSerialize(l[1],!0).length>=4?t(a):W(a)?i(a):n(a)}}const gc={name:"codeText",previous:yc,resolve:mc,tokenize:bc};function mc(e){let t=e.length-4,n=3,r,i;if((e[n][1].type==="lineEnding"||e[n][1].type==="space")&&(e[t][1].type==="lineEnding"||e[t][1].type==="space")){for(r=n;++r=this.left.length+this.right.length)throw new RangeError("Cannot access index `"+t+"` in a splice buffer of size `"+(this.left.length+this.right.length)+"`");return tthis.left.length?this.right.slice(this.right.length-r+this.left.length,this.right.length-t+this.left.length).reverse():this.left.slice(t).concat(this.right.slice(this.right.length-r+this.left.length).reverse())}splice(t,n,r){const i=n||0;this.setCursor(Math.trunc(t));const o=this.right.splice(this.right.length-i,Number.POSITIVE_INFINITY);return r&&Bt(this.left,r),o.reverse()}pop(){return this.setCursor(Number.POSITIVE_INFINITY),this.left.pop()}push(t){this.setCursor(Number.POSITIVE_INFINITY),this.left.push(t)}pushMany(t){this.setCursor(Number.POSITIVE_INFINITY),Bt(this.left,t)}unshift(t){this.setCursor(0),this.right.push(t)}unshiftMany(t){this.setCursor(0),Bt(this.right,t.reverse())}setCursor(t){if(!(t===this.left.length||t>this.left.length&&this.right.length===0||t<0&&this.left.length===0))if(t=4?t(a):e.interrupt(r.parser.constructs.flow,n,t)(a)}}function gl(e,t,n,r,i,o,a,l,s){const u=s||Number.POSITIVE_INFINITY;let p=0;return c;function c(x){return x===60?(e.enter(r),e.enter(i),e.enter(o),e.consume(x),e.exit(o),f):x===null||x===32||x===41||yn(x)?n(x):(e.enter(r),e.enter(a),e.enter(l),e.enter("chunkString",{contentType:"string"}),k(x))}function f(x){return x===62?(e.enter(o),e.consume(x),e.exit(o),e.exit(i),e.exit(r),t):(e.enter(l),e.enter("chunkString",{contentType:"string"}),d(x))}function d(x){return x===62?(e.exit("chunkString"),e.exit(l),f(x)):x===null||x===60||W(x)?n(x):(e.consume(x),x===92?g:d)}function g(x){return x===60||x===62||x===92?(e.consume(x),d):d(x)}function k(x){return!p&&(x===null||x===41||he(x))?(e.exit("chunkString"),e.exit(l),e.exit(a),e.exit(r),t(x)):p999||d===null||d===91||d===93&&!s||d===94&&!l&&"_hiddenFootnoteSupport"in a.parser.constructs?n(d):d===93?(e.exit(o),e.enter(i),e.consume(d),e.exit(i),e.exit(r),t):W(d)?(e.enter("lineEnding"),e.consume(d),e.exit("lineEnding"),p):(e.enter("chunkString",{contentType:"string"}),c(d))}function c(d){return d===null||d===91||d===93||W(d)||l++>999?(e.exit("chunkString"),p(d)):(e.consume(d),s||(s=!ne(d)),d===92?f:c)}function f(d){return d===91||d===92||d===93?(e.consume(d),l++,c):c(d)}}function yl(e,t,n,r,i,o){let a;return l;function l(f){return f===34||f===39||f===40?(e.enter(r),e.enter(i),e.consume(f),e.exit(i),a=f===40?41:f,s):n(f)}function s(f){return f===a?(e.enter(i),e.consume(f),e.exit(i),e.exit(r),t):(e.enter(o),u(f))}function u(f){return f===a?(e.exit(o),s(a)):f===null?n(f):W(f)?(e.enter("lineEnding"),e.consume(f),e.exit("lineEnding"),oe(e,u,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),p(f))}function p(f){return f===a||f===null||W(f)?(e.exit("chunkString"),u(f)):(e.consume(f),f===92?c:p)}function c(f){return f===a||f===92?(e.consume(f),p):p(f)}}function Ut(e,t){let n;return r;function r(i){return W(i)?(e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),n=!0,r):ne(i)?oe(e,r,n?"linePrefix":"lineSuffix")(i):t(i)}}const Cc={name:"definition",tokenize:Ac},Tc={partial:!0,tokenize:Lc};function Ac(e,t,n){const r=this;let i;return o;function o(d){return e.enter("definition"),a(d)}function a(d){return ml.call(r,e,l,n,"definitionLabel","definitionLabelMarker","definitionLabelString")(d)}function l(d){return i=Ke(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)),d===58?(e.enter("definitionMarker"),e.consume(d),e.exit("definitionMarker"),s):n(d)}function s(d){return he(d)?Ut(e,u)(d):u(d)}function u(d){return gl(e,p,n,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(d)}function p(d){return e.attempt(Tc,c,c)(d)}function c(d){return ne(d)?oe(e,f,"whitespace")(d):f(d)}function f(d){return d===null||W(d)?(e.exit("definition"),r.parser.defined.push(i),t(d)):n(d)}}function Lc(e,t,n){return r;function r(l){return he(l)?Ut(e,i)(l):n(l)}function i(l){return yl(e,o,n,"definitionTitle","definitionTitleMarker","definitionTitleString")(l)}function o(l){return ne(l)?oe(e,a,"whitespace")(l):a(l)}function a(l){return l===null||W(l)?t(l):n(l)}}const Nc={name:"hardBreakEscape",tokenize:Ic};function Ic(e,t,n){return r;function r(o){return e.enter("hardBreakEscape"),e.consume(o),i}function i(o){return W(o)?(e.exit("hardBreakEscape"),t(o)):n(o)}}const jc={name:"headingAtx",resolve:Rc,tokenize:Oc};function Rc(e,t){let n=e.length-2,r=3,i,o;return e[r][1].type==="whitespace"&&(r+=2),n-2>r&&e[n][1].type==="whitespace"&&(n-=2),e[n][1].type==="atxHeadingSequence"&&(r===n-1||n-4>r&&e[n-2][1].type==="whitespace")&&(n-=r+1===n?2:4),n>r&&(i={type:"atxHeadingText",start:e[r][1].start,end:e[n][1].end},o={type:"chunkText",start:e[r][1].start,end:e[n][1].end,contentType:"text"},Ve(e,r,n-r+1,[["enter",i,t],["enter",o,t],["exit",o,t],["exit",i,t]])),e}function Oc(e,t,n){let r=0;return i;function i(p){return e.enter("atxHeading"),o(p)}function o(p){return e.enter("atxHeadingSequence"),a(p)}function a(p){return p===35&&r++<6?(e.consume(p),a):p===null||he(p)?(e.exit("atxHeadingSequence"),l(p)):n(p)}function l(p){return p===35?(e.enter("atxHeadingSequence"),s(p)):p===null||W(p)?(e.exit("atxHeading"),t(p)):ne(p)?oe(e,l,"whitespace")(p):(e.enter("atxHeadingText"),u(p))}function s(p){return p===35?(e.consume(p),s):(e.exit("atxHeadingSequence"),l(p))}function u(p){return p===null||p===35||he(p)?(e.exit("atxHeadingText"),l(p)):(e.consume(p),u)}}const Dc=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],pa=["pre","script","style","textarea"],Mc={concrete:!0,name:"htmlFlow",resolveTo:Pc,tokenize:Bc},Fc={partial:!0,tokenize:qc},zc={partial:!0,tokenize:$c};function Pc(e){let t=e.length;for(;t--&&!(e[t][0]==="enter"&&e[t][1].type==="htmlFlow"););return t>1&&e[t-2][1].type==="linePrefix"&&(e[t][1].start=e[t-2][1].start,e[t+1][1].start=e[t-2][1].start,e.splice(t-2,2)),e}function Bc(e,t,n){const r=this;let i,o,a,l,s;return u;function u(b){return p(b)}function p(b){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(b),c}function c(b){return b===33?(e.consume(b),f):b===47?(e.consume(b),o=!0,k):b===63?(e.consume(b),i=3,r.interrupt?t:w):De(b)?(e.consume(b),a=String.fromCharCode(b),S):n(b)}function f(b){return b===45?(e.consume(b),i=2,d):b===91?(e.consume(b),i=5,l=0,g):De(b)?(e.consume(b),i=4,r.interrupt?t:w):n(b)}function d(b){return b===45?(e.consume(b),r.interrupt?t:w):n(b)}function g(b){const Z="CDATA[";return b===Z.charCodeAt(l++)?(e.consume(b),l===Z.length?r.interrupt?t:M:g):n(b)}function k(b){return De(b)?(e.consume(b),a=String.fromCharCode(b),S):n(b)}function S(b){if(b===null||b===47||b===62||he(b)){const Z=b===47,ee=a.toLowerCase();return!Z&&!o&&pa.includes(ee)?(i=1,r.interrupt?t(b):M(b)):Dc.includes(a.toLowerCase())?(i=6,Z?(e.consume(b),x):r.interrupt?t(b):M(b)):(i=7,r.interrupt&&!r.parser.lazy[r.now().line]?n(b):o?v(b):y(b))}return b===45||Re(b)?(e.consume(b),a+=String.fromCharCode(b),S):n(b)}function x(b){return b===62?(e.consume(b),r.interrupt?t:M):n(b)}function v(b){return ne(b)?(e.consume(b),v):E(b)}function y(b){return b===47?(e.consume(b),E):b===58||b===95||De(b)?(e.consume(b),_):ne(b)?(e.consume(b),y):E(b)}function _(b){return b===45||b===46||b===58||b===95||Re(b)?(e.consume(b),_):C(b)}function C(b){return b===61?(e.consume(b),m):ne(b)?(e.consume(b),C):y(b)}function m(b){return b===null||b===60||b===61||b===62||b===96?n(b):b===34||b===39?(e.consume(b),s=b,T):ne(b)?(e.consume(b),m):j(b)}function T(b){return b===s?(e.consume(b),s=null,A):b===null||W(b)?n(b):(e.consume(b),T)}function j(b){return b===null||b===34||b===39||b===47||b===60||b===61||b===62||b===96||he(b)?C(b):(e.consume(b),j)}function A(b){return b===47||b===62||ne(b)?y(b):n(b)}function E(b){return b===62?(e.consume(b),R):n(b)}function R(b){return b===null||W(b)?M(b):ne(b)?(e.consume(b),R):n(b)}function M(b){return b===45&&i===2?(e.consume(b),G):b===60&&i===1?(e.consume(b),J):b===62&&i===4?(e.consume(b),K):b===63&&i===3?(e.consume(b),w):b===93&&i===5?(e.consume(b),ie):W(b)&&(i===6||i===7)?(e.exit("htmlFlowData"),e.check(Fc,Y,H)(b)):b===null||W(b)?(e.exit("htmlFlowData"),H(b)):(e.consume(b),M)}function H(b){return e.check(zc,P,Y)(b)}function P(b){return e.enter("lineEnding"),e.consume(b),e.exit("lineEnding"),z}function z(b){return b===null||W(b)?H(b):(e.enter("htmlFlowData"),M(b))}function G(b){return b===45?(e.consume(b),w):M(b)}function J(b){return b===47?(e.consume(b),a="",U):M(b)}function U(b){if(b===62){const Z=a.toLowerCase();return pa.includes(Z)?(e.consume(b),K):M(b)}return De(b)&&a.length<8?(e.consume(b),a+=String.fromCharCode(b),U):M(b)}function ie(b){return b===93?(e.consume(b),w):M(b)}function w(b){return b===62?(e.consume(b),K):b===45&&i===2?(e.consume(b),w):M(b)}function K(b){return b===null||W(b)?(e.exit("htmlFlowData"),Y(b)):(e.consume(b),K)}function Y(b){return e.exit("htmlFlow"),t(b)}}function $c(e,t,n){const r=this;return i;function i(a){return W(a)?(e.enter("lineEnding"),e.consume(a),e.exit("lineEnding"),o):n(a)}function o(a){return r.parser.lazy[r.now().line]?n(a):t(a)}}function qc(e,t,n){return r;function r(i){return e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),e.attempt(Qt,t,n)}}const Uc={name:"htmlText",tokenize:Hc};function Hc(e,t,n){const r=this;let i,o,a;return l;function l(w){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(w),s}function s(w){return w===33?(e.consume(w),u):w===47?(e.consume(w),C):w===63?(e.consume(w),y):De(w)?(e.consume(w),j):n(w)}function u(w){return w===45?(e.consume(w),p):w===91?(e.consume(w),o=0,g):De(w)?(e.consume(w),v):n(w)}function p(w){return w===45?(e.consume(w),d):n(w)}function c(w){return w===null?n(w):w===45?(e.consume(w),f):W(w)?(a=c,J(w)):(e.consume(w),c)}function f(w){return w===45?(e.consume(w),d):c(w)}function d(w){return w===62?G(w):w===45?f(w):c(w)}function g(w){const K="CDATA[";return w===K.charCodeAt(o++)?(e.consume(w),o===K.length?k:g):n(w)}function k(w){return w===null?n(w):w===93?(e.consume(w),S):W(w)?(a=k,J(w)):(e.consume(w),k)}function S(w){return w===93?(e.consume(w),x):k(w)}function x(w){return w===62?G(w):w===93?(e.consume(w),x):k(w)}function v(w){return w===null||w===62?G(w):W(w)?(a=v,J(w)):(e.consume(w),v)}function y(w){return w===null?n(w):w===63?(e.consume(w),_):W(w)?(a=y,J(w)):(e.consume(w),y)}function _(w){return w===62?G(w):y(w)}function C(w){return De(w)?(e.consume(w),m):n(w)}function m(w){return w===45||Re(w)?(e.consume(w),m):T(w)}function T(w){return W(w)?(a=T,J(w)):ne(w)?(e.consume(w),T):G(w)}function j(w){return w===45||Re(w)?(e.consume(w),j):w===47||w===62||he(w)?A(w):n(w)}function A(w){return w===47?(e.consume(w),G):w===58||w===95||De(w)?(e.consume(w),E):W(w)?(a=A,J(w)):ne(w)?(e.consume(w),A):G(w)}function E(w){return w===45||w===46||w===58||w===95||Re(w)?(e.consume(w),E):R(w)}function R(w){return w===61?(e.consume(w),M):W(w)?(a=R,J(w)):ne(w)?(e.consume(w),R):A(w)}function M(w){return w===null||w===60||w===61||w===62||w===96?n(w):w===34||w===39?(e.consume(w),i=w,H):W(w)?(a=M,J(w)):ne(w)?(e.consume(w),M):(e.consume(w),P)}function H(w){return w===i?(e.consume(w),i=void 0,z):w===null?n(w):W(w)?(a=H,J(w)):(e.consume(w),H)}function P(w){return w===null||w===34||w===39||w===60||w===61||w===96?n(w):w===47||w===62||he(w)?A(w):(e.consume(w),P)}function z(w){return w===47||w===62||he(w)?A(w):n(w)}function G(w){return w===62?(e.consume(w),e.exit("htmlTextData"),e.exit("htmlText"),t):n(w)}function J(w){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(w),e.exit("lineEnding"),U}function U(w){return ne(w)?oe(e,ie,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(w):ie(w)}function ie(w){return e.enter("htmlTextData"),a(w)}}const Ni={name:"labelEnd",resolveAll:Zc,resolveTo:Xc,tokenize:Kc},Wc={tokenize:Yc},Vc={tokenize:Qc},Gc={tokenize:Jc};function Zc(e){let t=-1;const n=[];for(;++t=3&&(u===null||W(u))?(e.exit("thematicBreak"),t(u)):n(u)}function s(u){return u===i?(e.consume(u),r++,s):(e.exit("thematicBreakSequence"),ne(u)?oe(e,l,"whitespace")(u):l(u))}}const Pe={continuation:{tokenize:up},exit:pp,name:"list",tokenize:sp},op={partial:!0,tokenize:dp},lp={partial:!0,tokenize:cp};function sp(e,t,n){const r=this,i=r.events[r.events.length-1];let o=i&&i[1].type==="linePrefix"?i[2].sliceSerialize(i[1],!0).length:0,a=0;return l;function l(d){const g=r.containerState.type||(d===42||d===43||d===45?"listUnordered":"listOrdered");if(g==="listUnordered"?!r.containerState.marker||d===r.containerState.marker:li(d)){if(r.containerState.type||(r.containerState.type=g,e.enter(g,{_container:!0})),g==="listUnordered")return e.enter("listItemPrefix"),d===42||d===45?e.check(fn,n,u)(d):u(d);if(!r.interrupt||d===49)return e.enter("listItemPrefix"),e.enter("listItemValue"),s(d)}return n(d)}function s(d){return li(d)&&++a<10?(e.consume(d),s):(!r.interrupt||a<2)&&(r.containerState.marker?d===r.containerState.marker:d===41||d===46)?(e.exit("listItemValue"),u(d)):n(d)}function u(d){return e.enter("listItemMarker"),e.consume(d),e.exit("listItemMarker"),r.containerState.marker=r.containerState.marker||d,e.check(Qt,r.interrupt?n:p,e.attempt(op,f,c))}function p(d){return r.containerState.initialBlankLine=!0,o++,f(d)}function c(d){return ne(d)?(e.enter("listItemPrefixWhitespace"),e.consume(d),e.exit("listItemPrefixWhitespace"),f):n(d)}function f(d){return r.containerState.size=o+r.sliceSerialize(e.exit("listItemPrefix"),!0).length,t(d)}}function up(e,t,n){const r=this;return r.containerState._closeFlow=void 0,e.check(Qt,i,o);function i(l){return r.containerState.furtherBlankLines=r.containerState.furtherBlankLines||r.containerState.initialBlankLine,oe(e,t,"listItemIndent",r.containerState.size+1)(l)}function o(l){return r.containerState.furtherBlankLines||!ne(l)?(r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,a(l)):(r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,e.attempt(lp,t,a)(l))}function a(l){return r.containerState._closeFlow=!0,r.interrupt=void 0,oe(e,e.attempt(Pe,t,n),"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(l)}}function cp(e,t,n){const r=this;return oe(e,i,"listItemIndent",r.containerState.size+1);function i(o){const a=r.events[r.events.length-1];return a&&a[1].type==="listItemIndent"&&a[2].sliceSerialize(a[1],!0).length===r.containerState.size?t(o):n(o)}}function pp(e){e.exit(this.containerState.type)}function dp(e,t,n){const r=this;return oe(e,i,"listItemPrefixWhitespace",r.parser.constructs.disable.null.includes("codeIndented")?void 0:5);function i(o){const a=r.events[r.events.length-1];return!ne(o)&&a&&a[1].type==="listItemPrefixWhitespace"?t(o):n(o)}}const da={name:"setextUnderline",resolveTo:fp,tokenize:hp};function fp(e,t){let n=e.length,r,i,o;for(;n--;)if(e[n][0]==="enter"){if(e[n][1].type==="content"){r=n;break}e[n][1].type==="paragraph"&&(i=n)}else e[n][1].type==="content"&&e.splice(n,1),!o&&e[n][1].type==="definition"&&(o=n);const a={type:"setextHeading",start:{...e[r][1].start},end:{...e[e.length-1][1].end}};return e[i][1].type="setextHeadingText",o?(e.splice(i,0,["enter",a,t]),e.splice(o+1,0,["exit",e[r][1],t]),e[r][1].end={...e[o][1].end}):e[r][1]=a,e.push(["exit",a,t]),e}function hp(e,t,n){const r=this;let i;return o;function o(u){let p=r.events.length,c;for(;p--;)if(r.events[p][1].type!=="lineEnding"&&r.events[p][1].type!=="linePrefix"&&r.events[p][1].type!=="content"){c=r.events[p][1].type==="paragraph";break}return!r.parser.lazy[r.now().line]&&(r.interrupt||c)?(e.enter("setextHeadingLine"),i=u,a(u)):n(u)}function a(u){return e.enter("setextHeadingLineSequence"),l(u)}function l(u){return u===i?(e.consume(u),l):(e.exit("setextHeadingLineSequence"),ne(u)?oe(e,s,"lineSuffix")(u):s(u))}function s(u){return u===null||W(u)?(e.exit("setextHeadingLine"),t(u)):n(u)}}const gp={tokenize:mp};function mp(e){const t=this,n=e.attempt(Qt,r,e.attempt(this.parser.constructs.flowInitial,i,oe(e,e.attempt(this.parser.constructs.flow,i,e.attempt(vc,i)),"linePrefix")));return n;function r(o){if(o===null){e.consume(o);return}return e.enter("lineEndingBlank"),e.consume(o),e.exit("lineEndingBlank"),t.currentConstruct=void 0,n}function i(o){if(o===null){e.consume(o);return}return e.enter("lineEnding"),e.consume(o),e.exit("lineEnding"),t.currentConstruct=void 0,n}}const yp={resolveAll:xl()},bp=bl("string"),xp=bl("text");function bl(e){return{resolveAll:xl(e==="text"?kp:void 0),tokenize:t};function t(n){const r=this,i=this.parser.constructs[e],o=n.attempt(i,a,l);return a;function a(p){return u(p)?o(p):l(p)}function l(p){if(p===null){n.consume(p);return}return n.enter("data"),n.consume(p),s}function s(p){return u(p)?(n.exit("data"),o(p)):(n.consume(p),s)}function u(p){if(p===null)return!0;const c=i[p];let f=-1;if(c)for(;++f-1){const l=a[0];typeof l=="string"?a[0]=l.slice(r):a.shift()}o>0&&a.push(e[i].slice(0,o))}return a}function Rp(e,t){let n=-1;const r=[];let i;for(;++n4&&n.slice(0,4)==="data"&&uu.test(t)){if(t.charAt(4)==="-"){const o=t.slice(5).replace(Yi,du);r="data"+o.charAt(0).toUpperCase()+o.slice(1)}else{const o=t.slice(4);if(!Yi.test(o)){let a=o.replace(su,pu);a.charAt(0)!=="-"&&(a="-"+a),t="data"+a}}i=wi}return new i(r,t)}function pu(e){return"-"+e.toLowerCase()}function du(e){return e.charAt(1).toUpperCase()}const fu=Xo([Ko,au,Jo,el,tl],"html"),Si=Xo([Ko,ou,Jo,el,tl],"svg");function hu(e){return e.join(" ").trim()}var Et={},Fn,Qi;function gu(){if(Qi)return Fn;Qi=1;var e=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,t=/\n/g,n=/^\s*/,r=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,i=/^:\s*/,o=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,a=/^[;\s]*/,l=/^\s+|\s+$/g,s=`
+`,u="/",p="*",c="",f="comment",d="declaration";function g(S,x){if(typeof S!="string")throw new TypeError("First argument must be a string");if(!S)return[];x=x||{};var v=1,b=1;function _(P){var z=P.match(t);z&&(v+=z.length);var G=P.lastIndexOf(s);b=~G?P.length-G:b+P.length}function C(){var P={line:v,column:b};return function(z){return z.position=new m(P),A(),z}}function m(P){this.start=P,this.end={line:v,column:b},this.source=x.source}m.prototype.content=S;function T(P){var z=new Error(x.source+":"+v+":"+b+": "+P);if(z.reason=P,z.filename=x.source,z.line=v,z.column=b,z.source=S,!x.silent)throw z}function j(P){var z=P.exec(S);if(z){var G=z[0];return _(G),S=S.slice(G.length),z}}function A(){j(n)}function E(P){var z;for(P=P||[];z=R();)z!==!1&&P.push(z);return P}function R(){var P=C();if(!(u!=S.charAt(0)||p!=S.charAt(1))){for(var z=2;c!=S.charAt(z)&&(p!=S.charAt(z)||u!=S.charAt(z+1));)++z;if(z+=2,c===S.charAt(z-1))return T("End of comment missing");var G=S.slice(2,z-2);return b+=2,_(G),S=S.slice(z),b+=2,P({type:f,comment:G})}}function M(){var P=C(),z=j(r);if(z){if(R(),!j(i))return T("property missing ':'");var G=j(o),J=P({type:d,property:k(z[0].replace(e,c)),value:G?k(G[0].replace(e,c)):c});return j(a),J}}function H(){var P=[];E(P);for(var z;z=M();)z!==!1&&(P.push(z),E(P));return P}return A(),H()}function k(S){return S?S.replace(l,c):c}return Fn=g,Fn}var Ji;function mu(){if(Ji)return Et;Ji=1;var e=Et&&Et.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};Object.defineProperty(Et,"__esModule",{value:!0}),Et.default=n;const t=e(gu());function n(r,i){let o=null;if(!r||typeof r!="string")return o;const a=(0,t.default)(r),l=typeof i=="function";return a.forEach(s=>{if(s.type!=="declaration")return;const{property:u,value:p}=s;l?i(u,p,s):p&&(o=o||{},o[u]=p)}),o}return Et}var zt={},ea;function bu(){if(ea)return zt;ea=1,Object.defineProperty(zt,"__esModule",{value:!0}),zt.camelCase=void 0;var e=/^--[a-zA-Z0-9_-]+$/,t=/-([a-z])/g,n=/^[^-]+$/,r=/^-(webkit|moz|ms|o|khtml)-/,i=/^-(ms)-/,o=function(u){return!u||n.test(u)||e.test(u)},a=function(u,p){return p.toUpperCase()},l=function(u,p){return"".concat(p,"-")},s=function(u,p){return p===void 0&&(p={}),o(u)?u:(u=u.toLowerCase(),p.reactCompat?u=u.replace(i,l):u=u.replace(r,l),u.replace(t,a))};return zt.camelCase=s,zt}var Pt,ta;function yu(){if(ta)return Pt;ta=1;var e=Pt&&Pt.__importDefault||function(i){return i&&i.__esModule?i:{default:i}},t=e(mu()),n=bu();function r(i,o){var a={};return!i||typeof i!="string"||(0,t.default)(i,function(l,s){l&&s&&(a[(0,n.camelCase)(l,o)]=s)}),a}return r.default=r,Pt=r,Pt}var xu=yu();const ku=me(xu),nl=rl("end"),_i=rl("start");function rl(e){return t;function t(n){const r=n&&n.position&&n.position[e]||{};if(typeof r.line=="number"&&r.line>0&&typeof r.column=="number"&&r.column>0)return{line:r.line,column:r.column,offset:typeof r.offset=="number"&&r.offset>-1?r.offset:void 0}}}function vu(e){const t=_i(e),n=nl(e);if(t&&n)return{start:t,end:n}}function qt(e){return!e||typeof e!="object"?"":"position"in e||"type"in e?na(e.position):"start"in e||"end"in e?na(e):"line"in e||"column"in e?oi(e):""}function oi(e){return ra(e&&e.line)+":"+ra(e&&e.column)}function na(e){return oi(e&&e.start)+"-"+oi(e&&e.end)}function ra(e){return e&&typeof e=="number"?e:1}class Oe extends Error{constructor(t,n,r){super(),typeof n=="string"&&(r=n,n=void 0);let i="",o={},a=!1;if(n&&("line"in n&&"column"in n?o={place:n}:"start"in n&&"end"in n?o={place:n}:"type"in n?o={ancestors:[n],place:n.position}:o={...n}),typeof t=="string"?i=t:!o.cause&&t&&(a=!0,i=t.message,o.cause=t),!o.ruleId&&!o.source&&typeof r=="string"){const s=r.indexOf(":");s===-1?o.ruleId=r:(o.source=r.slice(0,s),o.ruleId=r.slice(s+1))}if(!o.place&&o.ancestors&&o.ancestors){const s=o.ancestors[o.ancestors.length-1];s&&(o.place=s.position)}const l=o.place&&"start"in o.place?o.place.start:o.place;this.ancestors=o.ancestors||void 0,this.cause=o.cause||void 0,this.column=l?l.column:void 0,this.fatal=void 0,this.file="",this.message=i,this.line=l?l.line:void 0,this.name=qt(o.place)||"1:1",this.place=o.place||void 0,this.reason=this.message,this.ruleId=o.ruleId||void 0,this.source=o.source||void 0,this.stack=a&&o.cause&&typeof o.cause.stack=="string"?o.cause.stack:"",this.actual=void 0,this.expected=void 0,this.note=void 0,this.url=void 0}}Oe.prototype.file="";Oe.prototype.name="";Oe.prototype.reason="";Oe.prototype.message="";Oe.prototype.stack="";Oe.prototype.column=void 0;Oe.prototype.line=void 0;Oe.prototype.ancestors=void 0;Oe.prototype.cause=void 0;Oe.prototype.fatal=void 0;Oe.prototype.place=void 0;Oe.prototype.ruleId=void 0;Oe.prototype.source=void 0;const Ei={}.hasOwnProperty,wu=new Map,Su=/[A-Z]/g,_u=new Set(["table","tbody","thead","tfoot","tr"]),Eu=new Set(["td","th"]),il="https://github.com/syntax-tree/hast-util-to-jsx-runtime";function Cu(e,t){if(!t||t.Fragment===void 0)throw new TypeError("Expected `Fragment` in options");const n=t.filePath||void 0;let r;if(t.development){if(typeof t.jsxDEV!="function")throw new TypeError("Expected `jsxDEV` in options when `development: true`");r=Ou(n,t.jsxDEV)}else{if(typeof t.jsx!="function")throw new TypeError("Expected `jsx` in production options");if(typeof t.jsxs!="function")throw new TypeError("Expected `jsxs` in production options");r=Ru(n,t.jsx,t.jsxs)}const i={Fragment:t.Fragment,ancestors:[],components:t.components||{},create:r,elementAttributeNameCase:t.elementAttributeNameCase||"react",evaluater:t.createEvaluater?t.createEvaluater():void 0,filePath:n,ignoreInvalidStyle:t.ignoreInvalidStyle||!1,passKeys:t.passKeys!==!1,passNode:t.passNode||!1,schema:t.space==="svg"?Si:fu,stylePropertyNameCase:t.stylePropertyNameCase||"dom",tableCellAlignToStyle:t.tableCellAlignToStyle!==!1},o=al(i,e,void 0);return o&&typeof o!="string"?o:i.create(e,i.Fragment,{children:o||void 0},void 0)}function al(e,t,n){if(t.type==="element")return Tu(e,t,n);if(t.type==="mdxFlowExpression"||t.type==="mdxTextExpression")return Au(e,t);if(t.type==="mdxJsxFlowElement"||t.type==="mdxJsxTextElement")return Nu(e,t,n);if(t.type==="mdxjsEsm")return Lu(e,t);if(t.type==="root")return Iu(e,t,n);if(t.type==="text")return ju(e,t)}function Tu(e,t,n){const r=e.schema;let i=r;t.tagName.toLowerCase()==="svg"&&r.space==="html"&&(i=Si,e.schema=i),e.ancestors.push(t);const o=ll(e,t.tagName,!1),a=Du(e,t);let l=Ti(e,t);return _u.has(t.tagName)&&(l=l.filter(function(s){return typeof s=="string"?!ru(s):!0})),ol(e,a,o,t),Ci(a,l),e.ancestors.pop(),e.schema=r,e.create(t,o,a,n)}function Au(e,t){if(t.data&&t.data.estree&&e.evaluater){const r=t.data.estree.body[0];return r.type,e.evaluater.evaluateExpression(r.expression)}Gt(e,t.position)}function Lu(e,t){if(t.data&&t.data.estree&&e.evaluater)return e.evaluater.evaluateProgram(t.data.estree);Gt(e,t.position)}function Nu(e,t,n){const r=e.schema;let i=r;t.name==="svg"&&r.space==="html"&&(i=Si,e.schema=i),e.ancestors.push(t);const o=t.name===null?e.Fragment:ll(e,t.name,!0),a=Mu(e,t),l=Ti(e,t);return ol(e,a,o,t),Ci(a,l),e.ancestors.pop(),e.schema=r,e.create(t,o,a,n)}function Iu(e,t,n){const r={};return Ci(r,Ti(e,t)),e.create(t,e.Fragment,r,n)}function ju(e,t){return t.value}function ol(e,t,n,r){typeof n!="string"&&n!==e.Fragment&&e.passNode&&(t.node=r)}function Ci(e,t){if(t.length>0){const n=t.length>1?t:t[0];n&&(e.children=n)}}function Ru(e,t,n){return r;function r(i,o,a,l){const u=Array.isArray(a.children)?n:t;return l?u(o,a,l):u(o,a)}}function Ou(e,t){return n;function n(r,i,o,a){const l=Array.isArray(o.children),s=_i(r);return t(i,o,a,l,{columnNumber:s?s.column-1:void 0,fileName:e,lineNumber:s?s.line:void 0},void 0)}}function Du(e,t){const n={};let r,i;for(i in t.properties)if(i!=="children"&&Ei.call(t.properties,i)){const o=Fu(e,i,t.properties[i]);if(o){const[a,l]=o;e.tableCellAlignToStyle&&a==="align"&&typeof l=="string"&&Eu.has(t.tagName)?r=l:n[a]=l}}if(r){const o=n.style||(n.style={});o[e.stylePropertyNameCase==="css"?"text-align":"textAlign"]=r}return n}function Mu(e,t){const n={};for(const r of t.attributes)if(r.type==="mdxJsxExpressionAttribute")if(r.data&&r.data.estree&&e.evaluater){const o=r.data.estree.body[0];o.type;const a=o.expression;a.type;const l=a.properties[0];l.type,Object.assign(n,e.evaluater.evaluateExpression(l.argument))}else Gt(e,t.position);else{const i=r.name;let o;if(r.value&&typeof r.value=="object")if(r.value.data&&r.value.data.estree&&e.evaluater){const l=r.value.data.estree.body[0];l.type,o=e.evaluater.evaluateExpression(l.expression)}else Gt(e,t.position);else o=r.value===null?!0:r.value;n[i]=o}return n}function Ti(e,t){const n=[];let r=-1;const i=e.passKeys?new Map:wu;for(;++ri?0:i+t:t=t>i?i:t,n=n>0?n:0,r.length<1e4)a=Array.from(r),a.unshift(t,n),e.splice(...a);else for(n&&e.splice(t,n);o0?(Ve(e,e.length,0,t),e):t}const oa={}.hasOwnProperty;function ul(e){const t={};let n=-1;for(;++n13&&n<32||n>126&&n<160||n>55295&&n<57344||n>64975&&n<65008||(n&65535)===65535||(n&65535)===65534||n>1114111?"�":String.fromCodePoint(n)}function Ke(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const De=pt(/[A-Za-z]/),Re=pt(/[\dA-Za-z]/),Vu=pt(/[#-'*+\--9=?A-Z^-~]/);function bn(e){return e!==null&&(e<32||e===127)}const li=pt(/\d/),Gu=pt(/[\dA-Fa-f]/),Zu=pt(/[!-/:-@[-`{-~]/);function W(e){return e!==null&&e<-2}function he(e){return e!==null&&(e<0||e===32)}function ne(e){return e===-2||e===-1||e===32}const En=pt(new RegExp("\\p{P}|\\p{S}","u")),kt=pt(/\s/);function pt(e){return t;function t(n){return n!==null&&n>-1&&e.test(String.fromCharCode(n))}}function Ot(e){const t=[];let n=-1,r=0,i=0;for(;++n55295&&o<57344){const l=e.charCodeAt(n+1);o<56320&&l>56319&&l<57344?(a=String.fromCharCode(o,l),i=1):a="�"}else a=String.fromCharCode(o);a&&(t.push(e.slice(r,n),encodeURIComponent(a)),r=n+i+1,a=""),i&&(n+=i,i=0)}return t.join("")+e.slice(r)}function oe(e,t,n,r){const i=r?r-1:Number.POSITIVE_INFINITY;let o=0;return a;function a(s){return ne(s)?(e.enter(n),l(s)):t(s)}function l(s){return ne(s)&&o++a))return;const T=t.events.length;let j=T,A,E;for(;j--;)if(t.events[j][0]==="exit"&&t.events[j][1].type==="chunkFlow"){if(A){E=t.events[j][1].end;break}A=!0}for(x(r),m=T;mb;){const C=n[_];t.containerState=C[1],C[0].exit.call(t,e)}n.length=b}function v(){i.write([null]),o=void 0,i=void 0,t.containerState._closeFlow=void 0}}function Ju(e,t,n){return oe(e,e.attempt(this.parser.constructs.document,t,n),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}function jt(e){if(e===null||he(e)||kt(e))return 1;if(En(e))return 2}function Cn(e,t,n){const r=[];let i=-1;for(;++i1&&e[n][1].end.offset-e[n][1].start.offset>1?2:1;const c={...e[r][1].end},f={...e[n][1].start};sa(c,-s),sa(f,s),a={type:s>1?"strongSequence":"emphasisSequence",start:c,end:{...e[r][1].end}},l={type:s>1?"strongSequence":"emphasisSequence",start:{...e[n][1].start},end:f},o={type:s>1?"strongText":"emphasisText",start:{...e[r][1].end},end:{...e[n][1].start}},i={type:s>1?"strong":"emphasis",start:{...a.start},end:{...l.end}},e[r][1].end={...a.start},e[n][1].start={...l.end},u=[],e[r][1].end.offset-e[r][1].start.offset&&(u=Ge(u,[["enter",e[r][1],t],["exit",e[r][1],t]])),u=Ge(u,[["enter",i,t],["enter",a,t],["exit",a,t],["enter",o,t]]),u=Ge(u,Cn(t.parser.constructs.insideSpan.null,e.slice(r+1,n),t)),u=Ge(u,[["exit",o,t],["enter",l,t],["exit",l,t],["exit",i,t]]),e[n][1].end.offset-e[n][1].start.offset?(p=2,u=Ge(u,[["enter",e[n][1],t],["exit",e[n][1],t]])):p=0,Ve(e,r-1,n-r+3,u),n=r+u.length-p-2;break}}for(n=-1;++n0&&ne(m)?oe(e,v,"linePrefix",o+1)(m):v(m)}function v(m){return m===null||W(m)?e.check(ua,k,_)(m):(e.enter("codeFlowValue"),b(m))}function b(m){return m===null||W(m)?(e.exit("codeFlowValue"),v(m)):(e.consume(m),b)}function _(m){return e.exit("codeFenced"),t(m)}function C(m,T,j){let A=0;return E;function E(z){return m.enter("lineEnding"),m.consume(z),m.exit("lineEnding"),R}function R(z){return m.enter("codeFencedFence"),ne(z)?oe(m,M,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(z):M(z)}function M(z){return z===l?(m.enter("codeFencedFenceSequence"),H(z)):j(z)}function H(z){return z===l?(A++,m.consume(z),H):A>=a?(m.exit("codeFencedFenceSequence"),ne(z)?oe(m,P,"whitespace")(z):P(z)):j(z)}function P(z){return z===null||W(z)?(m.exit("codeFencedFence"),T(z)):j(z)}}}function pc(e,t,n){const r=this;return i;function i(a){return a===null?n(a):(e.enter("lineEnding"),e.consume(a),e.exit("lineEnding"),o)}function o(a){return r.parser.lazy[r.now().line]?n(a):t(a)}}const Pn={name:"codeIndented",tokenize:fc},dc={partial:!0,tokenize:hc};function fc(e,t,n){const r=this;return i;function i(u){return e.enter("codeIndented"),oe(e,o,"linePrefix",5)(u)}function o(u){const p=r.events[r.events.length-1];return p&&p[1].type==="linePrefix"&&p[2].sliceSerialize(p[1],!0).length>=4?a(u):n(u)}function a(u){return u===null?s(u):W(u)?e.attempt(dc,a,s)(u):(e.enter("codeFlowValue"),l(u))}function l(u){return u===null||W(u)?(e.exit("codeFlowValue"),a(u)):(e.consume(u),l)}function s(u){return e.exit("codeIndented"),t(u)}}function hc(e,t,n){const r=this;return i;function i(a){return r.parser.lazy[r.now().line]?n(a):W(a)?(e.enter("lineEnding"),e.consume(a),e.exit("lineEnding"),i):oe(e,o,"linePrefix",5)(a)}function o(a){const l=r.events[r.events.length-1];return l&&l[1].type==="linePrefix"&&l[2].sliceSerialize(l[1],!0).length>=4?t(a):W(a)?i(a):n(a)}}const gc={name:"codeText",previous:bc,resolve:mc,tokenize:yc};function mc(e){let t=e.length-4,n=3,r,i;if((e[n][1].type==="lineEnding"||e[n][1].type==="space")&&(e[t][1].type==="lineEnding"||e[t][1].type==="space")){for(r=n;++r=this.left.length+this.right.length)throw new RangeError("Cannot access index `"+t+"` in a splice buffer of size `"+(this.left.length+this.right.length)+"`");return tthis.left.length?this.right.slice(this.right.length-r+this.left.length,this.right.length-t+this.left.length).reverse():this.left.slice(t).concat(this.right.slice(this.right.length-r+this.left.length).reverse())}splice(t,n,r){const i=n||0;this.setCursor(Math.trunc(t));const o=this.right.splice(this.right.length-i,Number.POSITIVE_INFINITY);return r&&Bt(this.left,r),o.reverse()}pop(){return this.setCursor(Number.POSITIVE_INFINITY),this.left.pop()}push(t){this.setCursor(Number.POSITIVE_INFINITY),this.left.push(t)}pushMany(t){this.setCursor(Number.POSITIVE_INFINITY),Bt(this.left,t)}unshift(t){this.setCursor(0),this.right.push(t)}unshiftMany(t){this.setCursor(0),Bt(this.right,t.reverse())}setCursor(t){if(!(t===this.left.length||t>this.left.length&&this.right.length===0||t<0&&this.left.length===0))if(t=4?t(a):e.interrupt(r.parser.constructs.flow,n,t)(a)}}function gl(e,t,n,r,i,o,a,l,s){const u=s||Number.POSITIVE_INFINITY;let p=0;return c;function c(x){return x===60?(e.enter(r),e.enter(i),e.enter(o),e.consume(x),e.exit(o),f):x===null||x===32||x===41||bn(x)?n(x):(e.enter(r),e.enter(a),e.enter(l),e.enter("chunkString",{contentType:"string"}),k(x))}function f(x){return x===62?(e.enter(o),e.consume(x),e.exit(o),e.exit(i),e.exit(r),t):(e.enter(l),e.enter("chunkString",{contentType:"string"}),d(x))}function d(x){return x===62?(e.exit("chunkString"),e.exit(l),f(x)):x===null||x===60||W(x)?n(x):(e.consume(x),x===92?g:d)}function g(x){return x===60||x===62||x===92?(e.consume(x),d):d(x)}function k(x){return!p&&(x===null||x===41||he(x))?(e.exit("chunkString"),e.exit(l),e.exit(a),e.exit(r),t(x)):p999||d===null||d===91||d===93&&!s||d===94&&!l&&"_hiddenFootnoteSupport"in a.parser.constructs?n(d):d===93?(e.exit(o),e.enter(i),e.consume(d),e.exit(i),e.exit(r),t):W(d)?(e.enter("lineEnding"),e.consume(d),e.exit("lineEnding"),p):(e.enter("chunkString",{contentType:"string"}),c(d))}function c(d){return d===null||d===91||d===93||W(d)||l++>999?(e.exit("chunkString"),p(d)):(e.consume(d),s||(s=!ne(d)),d===92?f:c)}function f(d){return d===91||d===92||d===93?(e.consume(d),l++,c):c(d)}}function bl(e,t,n,r,i,o){let a;return l;function l(f){return f===34||f===39||f===40?(e.enter(r),e.enter(i),e.consume(f),e.exit(i),a=f===40?41:f,s):n(f)}function s(f){return f===a?(e.enter(i),e.consume(f),e.exit(i),e.exit(r),t):(e.enter(o),u(f))}function u(f){return f===a?(e.exit(o),s(a)):f===null?n(f):W(f)?(e.enter("lineEnding"),e.consume(f),e.exit("lineEnding"),oe(e,u,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),p(f))}function p(f){return f===a||f===null||W(f)?(e.exit("chunkString"),u(f)):(e.consume(f),f===92?c:p)}function c(f){return f===a||f===92?(e.consume(f),p):p(f)}}function Ut(e,t){let n;return r;function r(i){return W(i)?(e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),n=!0,r):ne(i)?oe(e,r,n?"linePrefix":"lineSuffix")(i):t(i)}}const Cc={name:"definition",tokenize:Ac},Tc={partial:!0,tokenize:Lc};function Ac(e,t,n){const r=this;let i;return o;function o(d){return e.enter("definition"),a(d)}function a(d){return ml.call(r,e,l,n,"definitionLabel","definitionLabelMarker","definitionLabelString")(d)}function l(d){return i=Ke(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)),d===58?(e.enter("definitionMarker"),e.consume(d),e.exit("definitionMarker"),s):n(d)}function s(d){return he(d)?Ut(e,u)(d):u(d)}function u(d){return gl(e,p,n,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(d)}function p(d){return e.attempt(Tc,c,c)(d)}function c(d){return ne(d)?oe(e,f,"whitespace")(d):f(d)}function f(d){return d===null||W(d)?(e.exit("definition"),r.parser.defined.push(i),t(d)):n(d)}}function Lc(e,t,n){return r;function r(l){return he(l)?Ut(e,i)(l):n(l)}function i(l){return bl(e,o,n,"definitionTitle","definitionTitleMarker","definitionTitleString")(l)}function o(l){return ne(l)?oe(e,a,"whitespace")(l):a(l)}function a(l){return l===null||W(l)?t(l):n(l)}}const Nc={name:"hardBreakEscape",tokenize:Ic};function Ic(e,t,n){return r;function r(o){return e.enter("hardBreakEscape"),e.consume(o),i}function i(o){return W(o)?(e.exit("hardBreakEscape"),t(o)):n(o)}}const jc={name:"headingAtx",resolve:Rc,tokenize:Oc};function Rc(e,t){let n=e.length-2,r=3,i,o;return e[r][1].type==="whitespace"&&(r+=2),n-2>r&&e[n][1].type==="whitespace"&&(n-=2),e[n][1].type==="atxHeadingSequence"&&(r===n-1||n-4>r&&e[n-2][1].type==="whitespace")&&(n-=r+1===n?2:4),n>r&&(i={type:"atxHeadingText",start:e[r][1].start,end:e[n][1].end},o={type:"chunkText",start:e[r][1].start,end:e[n][1].end,contentType:"text"},Ve(e,r,n-r+1,[["enter",i,t],["enter",o,t],["exit",o,t],["exit",i,t]])),e}function Oc(e,t,n){let r=0;return i;function i(p){return e.enter("atxHeading"),o(p)}function o(p){return e.enter("atxHeadingSequence"),a(p)}function a(p){return p===35&&r++<6?(e.consume(p),a):p===null||he(p)?(e.exit("atxHeadingSequence"),l(p)):n(p)}function l(p){return p===35?(e.enter("atxHeadingSequence"),s(p)):p===null||W(p)?(e.exit("atxHeading"),t(p)):ne(p)?oe(e,l,"whitespace")(p):(e.enter("atxHeadingText"),u(p))}function s(p){return p===35?(e.consume(p),s):(e.exit("atxHeadingSequence"),l(p))}function u(p){return p===null||p===35||he(p)?(e.exit("atxHeadingText"),l(p)):(e.consume(p),u)}}const Dc=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],pa=["pre","script","style","textarea"],Mc={concrete:!0,name:"htmlFlow",resolveTo:Pc,tokenize:Bc},Fc={partial:!0,tokenize:qc},zc={partial:!0,tokenize:$c};function Pc(e){let t=e.length;for(;t--&&!(e[t][0]==="enter"&&e[t][1].type==="htmlFlow"););return t>1&&e[t-2][1].type==="linePrefix"&&(e[t][1].start=e[t-2][1].start,e[t+1][1].start=e[t-2][1].start,e.splice(t-2,2)),e}function Bc(e,t,n){const r=this;let i,o,a,l,s;return u;function u(y){return p(y)}function p(y){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(y),c}function c(y){return y===33?(e.consume(y),f):y===47?(e.consume(y),o=!0,k):y===63?(e.consume(y),i=3,r.interrupt?t:w):De(y)?(e.consume(y),a=String.fromCharCode(y),S):n(y)}function f(y){return y===45?(e.consume(y),i=2,d):y===91?(e.consume(y),i=5,l=0,g):De(y)?(e.consume(y),i=4,r.interrupt?t:w):n(y)}function d(y){return y===45?(e.consume(y),r.interrupt?t:w):n(y)}function g(y){const Z="CDATA[";return y===Z.charCodeAt(l++)?(e.consume(y),l===Z.length?r.interrupt?t:M:g):n(y)}function k(y){return De(y)?(e.consume(y),a=String.fromCharCode(y),S):n(y)}function S(y){if(y===null||y===47||y===62||he(y)){const Z=y===47,ee=a.toLowerCase();return!Z&&!o&&pa.includes(ee)?(i=1,r.interrupt?t(y):M(y)):Dc.includes(a.toLowerCase())?(i=6,Z?(e.consume(y),x):r.interrupt?t(y):M(y)):(i=7,r.interrupt&&!r.parser.lazy[r.now().line]?n(y):o?v(y):b(y))}return y===45||Re(y)?(e.consume(y),a+=String.fromCharCode(y),S):n(y)}function x(y){return y===62?(e.consume(y),r.interrupt?t:M):n(y)}function v(y){return ne(y)?(e.consume(y),v):E(y)}function b(y){return y===47?(e.consume(y),E):y===58||y===95||De(y)?(e.consume(y),_):ne(y)?(e.consume(y),b):E(y)}function _(y){return y===45||y===46||y===58||y===95||Re(y)?(e.consume(y),_):C(y)}function C(y){return y===61?(e.consume(y),m):ne(y)?(e.consume(y),C):b(y)}function m(y){return y===null||y===60||y===61||y===62||y===96?n(y):y===34||y===39?(e.consume(y),s=y,T):ne(y)?(e.consume(y),m):j(y)}function T(y){return y===s?(e.consume(y),s=null,A):y===null||W(y)?n(y):(e.consume(y),T)}function j(y){return y===null||y===34||y===39||y===47||y===60||y===61||y===62||y===96||he(y)?C(y):(e.consume(y),j)}function A(y){return y===47||y===62||ne(y)?b(y):n(y)}function E(y){return y===62?(e.consume(y),R):n(y)}function R(y){return y===null||W(y)?M(y):ne(y)?(e.consume(y),R):n(y)}function M(y){return y===45&&i===2?(e.consume(y),G):y===60&&i===1?(e.consume(y),J):y===62&&i===4?(e.consume(y),K):y===63&&i===3?(e.consume(y),w):y===93&&i===5?(e.consume(y),ie):W(y)&&(i===6||i===7)?(e.exit("htmlFlowData"),e.check(Fc,Y,H)(y)):y===null||W(y)?(e.exit("htmlFlowData"),H(y)):(e.consume(y),M)}function H(y){return e.check(zc,P,Y)(y)}function P(y){return e.enter("lineEnding"),e.consume(y),e.exit("lineEnding"),z}function z(y){return y===null||W(y)?H(y):(e.enter("htmlFlowData"),M(y))}function G(y){return y===45?(e.consume(y),w):M(y)}function J(y){return y===47?(e.consume(y),a="",U):M(y)}function U(y){if(y===62){const Z=a.toLowerCase();return pa.includes(Z)?(e.consume(y),K):M(y)}return De(y)&&a.length<8?(e.consume(y),a+=String.fromCharCode(y),U):M(y)}function ie(y){return y===93?(e.consume(y),w):M(y)}function w(y){return y===62?(e.consume(y),K):y===45&&i===2?(e.consume(y),w):M(y)}function K(y){return y===null||W(y)?(e.exit("htmlFlowData"),Y(y)):(e.consume(y),K)}function Y(y){return e.exit("htmlFlow"),t(y)}}function $c(e,t,n){const r=this;return i;function i(a){return W(a)?(e.enter("lineEnding"),e.consume(a),e.exit("lineEnding"),o):n(a)}function o(a){return r.parser.lazy[r.now().line]?n(a):t(a)}}function qc(e,t,n){return r;function r(i){return e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),e.attempt(Qt,t,n)}}const Uc={name:"htmlText",tokenize:Hc};function Hc(e,t,n){const r=this;let i,o,a;return l;function l(w){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(w),s}function s(w){return w===33?(e.consume(w),u):w===47?(e.consume(w),C):w===63?(e.consume(w),b):De(w)?(e.consume(w),j):n(w)}function u(w){return w===45?(e.consume(w),p):w===91?(e.consume(w),o=0,g):De(w)?(e.consume(w),v):n(w)}function p(w){return w===45?(e.consume(w),d):n(w)}function c(w){return w===null?n(w):w===45?(e.consume(w),f):W(w)?(a=c,J(w)):(e.consume(w),c)}function f(w){return w===45?(e.consume(w),d):c(w)}function d(w){return w===62?G(w):w===45?f(w):c(w)}function g(w){const K="CDATA[";return w===K.charCodeAt(o++)?(e.consume(w),o===K.length?k:g):n(w)}function k(w){return w===null?n(w):w===93?(e.consume(w),S):W(w)?(a=k,J(w)):(e.consume(w),k)}function S(w){return w===93?(e.consume(w),x):k(w)}function x(w){return w===62?G(w):w===93?(e.consume(w),x):k(w)}function v(w){return w===null||w===62?G(w):W(w)?(a=v,J(w)):(e.consume(w),v)}function b(w){return w===null?n(w):w===63?(e.consume(w),_):W(w)?(a=b,J(w)):(e.consume(w),b)}function _(w){return w===62?G(w):b(w)}function C(w){return De(w)?(e.consume(w),m):n(w)}function m(w){return w===45||Re(w)?(e.consume(w),m):T(w)}function T(w){return W(w)?(a=T,J(w)):ne(w)?(e.consume(w),T):G(w)}function j(w){return w===45||Re(w)?(e.consume(w),j):w===47||w===62||he(w)?A(w):n(w)}function A(w){return w===47?(e.consume(w),G):w===58||w===95||De(w)?(e.consume(w),E):W(w)?(a=A,J(w)):ne(w)?(e.consume(w),A):G(w)}function E(w){return w===45||w===46||w===58||w===95||Re(w)?(e.consume(w),E):R(w)}function R(w){return w===61?(e.consume(w),M):W(w)?(a=R,J(w)):ne(w)?(e.consume(w),R):A(w)}function M(w){return w===null||w===60||w===61||w===62||w===96?n(w):w===34||w===39?(e.consume(w),i=w,H):W(w)?(a=M,J(w)):ne(w)?(e.consume(w),M):(e.consume(w),P)}function H(w){return w===i?(e.consume(w),i=void 0,z):w===null?n(w):W(w)?(a=H,J(w)):(e.consume(w),H)}function P(w){return w===null||w===34||w===39||w===60||w===61||w===96?n(w):w===47||w===62||he(w)?A(w):(e.consume(w),P)}function z(w){return w===47||w===62||he(w)?A(w):n(w)}function G(w){return w===62?(e.consume(w),e.exit("htmlTextData"),e.exit("htmlText"),t):n(w)}function J(w){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(w),e.exit("lineEnding"),U}function U(w){return ne(w)?oe(e,ie,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(w):ie(w)}function ie(w){return e.enter("htmlTextData"),a(w)}}const Ni={name:"labelEnd",resolveAll:Zc,resolveTo:Xc,tokenize:Kc},Wc={tokenize:Yc},Vc={tokenize:Qc},Gc={tokenize:Jc};function Zc(e){let t=-1;const n=[];for(;++t=3&&(u===null||W(u))?(e.exit("thematicBreak"),t(u)):n(u)}function s(u){return u===i?(e.consume(u),r++,s):(e.exit("thematicBreakSequence"),ne(u)?oe(e,l,"whitespace")(u):l(u))}}const Pe={continuation:{tokenize:up},exit:pp,name:"list",tokenize:sp},op={partial:!0,tokenize:dp},lp={partial:!0,tokenize:cp};function sp(e,t,n){const r=this,i=r.events[r.events.length-1];let o=i&&i[1].type==="linePrefix"?i[2].sliceSerialize(i[1],!0).length:0,a=0;return l;function l(d){const g=r.containerState.type||(d===42||d===43||d===45?"listUnordered":"listOrdered");if(g==="listUnordered"?!r.containerState.marker||d===r.containerState.marker:li(d)){if(r.containerState.type||(r.containerState.type=g,e.enter(g,{_container:!0})),g==="listUnordered")return e.enter("listItemPrefix"),d===42||d===45?e.check(fn,n,u)(d):u(d);if(!r.interrupt||d===49)return e.enter("listItemPrefix"),e.enter("listItemValue"),s(d)}return n(d)}function s(d){return li(d)&&++a<10?(e.consume(d),s):(!r.interrupt||a<2)&&(r.containerState.marker?d===r.containerState.marker:d===41||d===46)?(e.exit("listItemValue"),u(d)):n(d)}function u(d){return e.enter("listItemMarker"),e.consume(d),e.exit("listItemMarker"),r.containerState.marker=r.containerState.marker||d,e.check(Qt,r.interrupt?n:p,e.attempt(op,f,c))}function p(d){return r.containerState.initialBlankLine=!0,o++,f(d)}function c(d){return ne(d)?(e.enter("listItemPrefixWhitespace"),e.consume(d),e.exit("listItemPrefixWhitespace"),f):n(d)}function f(d){return r.containerState.size=o+r.sliceSerialize(e.exit("listItemPrefix"),!0).length,t(d)}}function up(e,t,n){const r=this;return r.containerState._closeFlow=void 0,e.check(Qt,i,o);function i(l){return r.containerState.furtherBlankLines=r.containerState.furtherBlankLines||r.containerState.initialBlankLine,oe(e,t,"listItemIndent",r.containerState.size+1)(l)}function o(l){return r.containerState.furtherBlankLines||!ne(l)?(r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,a(l)):(r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,e.attempt(lp,t,a)(l))}function a(l){return r.containerState._closeFlow=!0,r.interrupt=void 0,oe(e,e.attempt(Pe,t,n),"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(l)}}function cp(e,t,n){const r=this;return oe(e,i,"listItemIndent",r.containerState.size+1);function i(o){const a=r.events[r.events.length-1];return a&&a[1].type==="listItemIndent"&&a[2].sliceSerialize(a[1],!0).length===r.containerState.size?t(o):n(o)}}function pp(e){e.exit(this.containerState.type)}function dp(e,t,n){const r=this;return oe(e,i,"listItemPrefixWhitespace",r.parser.constructs.disable.null.includes("codeIndented")?void 0:5);function i(o){const a=r.events[r.events.length-1];return!ne(o)&&a&&a[1].type==="listItemPrefixWhitespace"?t(o):n(o)}}const da={name:"setextUnderline",resolveTo:fp,tokenize:hp};function fp(e,t){let n=e.length,r,i,o;for(;n--;)if(e[n][0]==="enter"){if(e[n][1].type==="content"){r=n;break}e[n][1].type==="paragraph"&&(i=n)}else e[n][1].type==="content"&&e.splice(n,1),!o&&e[n][1].type==="definition"&&(o=n);const a={type:"setextHeading",start:{...e[r][1].start},end:{...e[e.length-1][1].end}};return e[i][1].type="setextHeadingText",o?(e.splice(i,0,["enter",a,t]),e.splice(o+1,0,["exit",e[r][1],t]),e[r][1].end={...e[o][1].end}):e[r][1]=a,e.push(["exit",a,t]),e}function hp(e,t,n){const r=this;let i;return o;function o(u){let p=r.events.length,c;for(;p--;)if(r.events[p][1].type!=="lineEnding"&&r.events[p][1].type!=="linePrefix"&&r.events[p][1].type!=="content"){c=r.events[p][1].type==="paragraph";break}return!r.parser.lazy[r.now().line]&&(r.interrupt||c)?(e.enter("setextHeadingLine"),i=u,a(u)):n(u)}function a(u){return e.enter("setextHeadingLineSequence"),l(u)}function l(u){return u===i?(e.consume(u),l):(e.exit("setextHeadingLineSequence"),ne(u)?oe(e,s,"lineSuffix")(u):s(u))}function s(u){return u===null||W(u)?(e.exit("setextHeadingLine"),t(u)):n(u)}}const gp={tokenize:mp};function mp(e){const t=this,n=e.attempt(Qt,r,e.attempt(this.parser.constructs.flowInitial,i,oe(e,e.attempt(this.parser.constructs.flow,i,e.attempt(vc,i)),"linePrefix")));return n;function r(o){if(o===null){e.consume(o);return}return e.enter("lineEndingBlank"),e.consume(o),e.exit("lineEndingBlank"),t.currentConstruct=void 0,n}function i(o){if(o===null){e.consume(o);return}return e.enter("lineEnding"),e.consume(o),e.exit("lineEnding"),t.currentConstruct=void 0,n}}const bp={resolveAll:xl()},yp=yl("string"),xp=yl("text");function yl(e){return{resolveAll:xl(e==="text"?kp:void 0),tokenize:t};function t(n){const r=this,i=this.parser.constructs[e],o=n.attempt(i,a,l);return a;function a(p){return u(p)?o(p):l(p)}function l(p){if(p===null){n.consume(p);return}return n.enter("data"),n.consume(p),s}function s(p){return u(p)?(n.exit("data"),o(p)):(n.consume(p),s)}function u(p){if(p===null)return!0;const c=i[p];let f=-1;if(c)for(;++f-1){const l=a[0];typeof l=="string"?a[0]=l.slice(r):a.shift()}o>0&&a.push(e[i].slice(0,o))}return a}function Rp(e,t){let n=-1;const r=[];let i;for(;++n0){const ke=B.tokenStack[B.tokenStack.length-1];(ke[1]||ha).call(B,void 0,ke[0])}for(D.position={start:st(L.length>0?L[0][1].start:{line:1,column:1,offset:0}),end:st(L.length>0?L[L.length-2][1].end:{line:1,column:1,offset:0})},re=-1;++re0){const ke=B.tokenStack[B.tokenStack.length-1];(ke[1]||ha).call(B,void 0,ke[0])}for(D.position={start:st(L.length>0?L[0][1].start:{line:1,column:1,offset:0}),end:st(L.length>0?L[L.length-2][1].end:{line:1,column:1,offset:0})},re=-1;++re0&&(r.className=["language-"+i[0]]);let o={type:"element",tagName:"code",properties:r,children:[{type:"text",value:n}]};return t.meta&&(o.data={meta:t.meta}),e.patch(t,o),o=e.applyData(t,o),o={type:"element",tagName:"pre",properties:{},children:[o]},e.patch(t,o),o}function Gp(e,t){const n={type:"element",tagName:"del",properties:{},children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}function Zp(e,t){const n={type:"element",tagName:"em",properties:{},children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}function Xp(e,t){const n=typeof e.options.clobberPrefix=="string"?e.options.clobberPrefix:"user-content-",r=String(t.identifier).toUpperCase(),i=Ot(r.toLowerCase()),o=e.footnoteOrder.indexOf(r);let a,l=e.footnoteCounts.get(r);l===void 0?(l=0,e.footnoteOrder.push(r),a=e.footnoteOrder.length):a=o+1,l+=1,e.footnoteCounts.set(r,l);const s={type:"element",tagName:"a",properties:{href:"#"+n+"fn-"+i,id:n+"fnref-"+i+(l>1?"-"+l:""),dataFootnoteRef:!0,ariaDescribedBy:["footnote-label"]},children:[{type:"text",value:String(a)}]};e.patch(t,s);const u={type:"element",tagName:"sup",properties:{},children:[s]};return e.patch(t,u),e.applyData(t,u)}function Kp(e,t){const n={type:"element",tagName:"h"+t.depth,properties:{},children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}function Yp(e,t){if(e.options.allowDangerousHtml){const n={type:"raw",value:t.value};return e.patch(t,n),e.applyData(t,n)}}function wl(e,t){const n=t.referenceType;let r="]";if(n==="collapsed"?r+="[]":n==="full"&&(r+="["+(t.label||t.identifier)+"]"),t.type==="imageReference")return[{type:"text",value:"!["+t.alt+r}];const i=e.all(t),o=i[0];o&&o.type==="text"?o.value="["+o.value:i.unshift({type:"text",value:"["});const a=i[i.length-1];return a&&a.type==="text"?a.value+=r:i.push({type:"text",value:r}),i}function Qp(e,t){const n=String(t.identifier).toUpperCase(),r=e.definitionById.get(n);if(!r)return wl(e,t);const i={src:Ot(r.url||""),alt:t.alt};r.title!==null&&r.title!==void 0&&(i.title=r.title);const o={type:"element",tagName:"img",properties:i,children:[]};return e.patch(t,o),e.applyData(t,o)}function Jp(e,t){const n={src:Ot(t.url)};t.alt!==null&&t.alt!==void 0&&(n.alt=t.alt),t.title!==null&&t.title!==void 0&&(n.title=t.title);const r={type:"element",tagName:"img",properties:n,children:[]};return e.patch(t,r),e.applyData(t,r)}function ed(e,t){const n={type:"text",value:t.value.replace(/\r?\n|\r/g," ")};e.patch(t,n);const r={type:"element",tagName:"code",properties:{},children:[n]};return e.patch(t,r),e.applyData(t,r)}function td(e,t){const n=String(t.identifier).toUpperCase(),r=e.definitionById.get(n);if(!r)return wl(e,t);const i={href:Ot(r.url||"")};r.title!==null&&r.title!==void 0&&(i.title=r.title);const o={type:"element",tagName:"a",properties:i,children:e.all(t)};return e.patch(t,o),e.applyData(t,o)}function nd(e,t){const n={href:Ot(t.url)};t.title!==null&&t.title!==void 0&&(n.title=t.title);const r={type:"element",tagName:"a",properties:n,children:e.all(t)};return e.patch(t,r),e.applyData(t,r)}function rd(e,t,n){const r=e.all(t),i=n?id(n):Sl(t),o={},a=[];if(typeof t.checked=="boolean"){const p=r[0];let c;p&&p.type==="element"&&p.tagName==="p"?c=p:(c={type:"element",tagName:"p",properties:{},children:[]},r.unshift(c)),c.children.length>0&&c.children.unshift({type:"text",value:" "}),c.children.unshift({type:"element",tagName:"input",properties:{type:"checkbox",checked:t.checked,disabled:!0},children:[]}),o.className=["task-list-item"]}let l=-1;for(;++l1}function ad(e,t){const n={},r=e.all(t);let i=-1;for(typeof t.start=="number"&&t.start!==1&&(n.start=t.start);++i0){const a={type:"element",tagName:"tbody",properties:{},children:e.wrap(n,!0)},l=_i(t.children[1]),s=nl(t.children[t.children.length-1]);l&&s&&(a.position={start:l,end:s}),i.push(a)}const o={type:"element",tagName:"table",properties:{},children:e.wrap(i,!0)};return e.patch(t,o),e.applyData(t,o)}function cd(e,t,n){const r=n?n.children:void 0,o=(r?r.indexOf(t):1)===0?"th":"td",a=n&&n.type==="table"?n.align:void 0,l=a?a.length:t.children.length;let s=-1;const u=[];for(;++s0,!0),r[0]),i=r.index+r[0].length,r=n.exec(t);return o.push(ya(t.slice(i),i>0,!1)),o.join("")}function ya(e,t,n){let r=0,i=e.length;if(t){let o=e.codePointAt(r);for(;o===ga||o===ma;)r++,o=e.codePointAt(r)}if(n){let o=e.codePointAt(i-1);for(;o===ga||o===ma;)i--,o=e.codePointAt(i-1)}return i>r?e.slice(r,i):""}function fd(e,t){const n={type:"text",value:dd(String(t.value))};return e.patch(t,n),e.applyData(t,n)}function hd(e,t){const n={type:"element",tagName:"hr",properties:{},children:[]};return e.patch(t,n),e.applyData(t,n)}const gd={blockquote:Hp,break:Wp,code:Vp,delete:Gp,emphasis:Zp,footnoteReference:Xp,heading:Kp,html:Yp,imageReference:Qp,image:Jp,inlineCode:ed,linkReference:td,link:nd,listItem:rd,list:ad,paragraph:od,root:ld,strong:sd,table:ud,tableCell:pd,tableRow:cd,text:fd,thematicBreak:hd,toml:ln,yaml:ln,definition:ln,footnoteDefinition:ln};function ln(){}const _l=-1,Tn=0,Ht=1,bn=2,Ii=3,ji=4,Ri=5,Oi=6,El=7,Cl=8,ba=typeof self=="object"?self:globalThis,md=(e,t)=>{const n=(i,o)=>(e.set(o,i),i),r=i=>{if(e.has(i))return e.get(i);const[o,a]=t[i];switch(o){case Tn:case _l:return n(a,i);case Ht:{const l=n([],i);for(const s of a)l.push(r(s));return l}case bn:{const l=n({},i);for(const[s,u]of a)l[r(s)]=r(u);return l}case Ii:return n(new Date(a),i);case ji:{const{source:l,flags:s}=a;return n(new RegExp(l,s),i)}case Ri:{const l=n(new Map,i);for(const[s,u]of a)l.set(r(s),r(u));return l}case Oi:{const l=n(new Set,i);for(const s of a)l.add(r(s));return l}case El:{const{name:l,message:s}=a;return n(new ba[l](s),i)}case Cl:return n(BigInt(a),i);case"BigInt":return n(Object(BigInt(a)),i);case"ArrayBuffer":return n(new Uint8Array(a).buffer,a);case"DataView":{const{buffer:l}=new Uint8Array(a);return n(new DataView(l),a)}}return n(new ba[o](a),i)};return r},xa=e=>md(new Map,e)(0),Ct="",{toString:yd}={},{keys:bd}=Object,$t=e=>{const t=typeof e;if(t!=="object"||!e)return[Tn,t];const n=yd.call(e).slice(8,-1);switch(n){case"Array":return[Ht,Ct];case"Object":return[bn,Ct];case"Date":return[Ii,Ct];case"RegExp":return[ji,Ct];case"Map":return[Ri,Ct];case"Set":return[Oi,Ct];case"DataView":return[Ht,n]}return n.includes("Array")?[Ht,n]:n.includes("Error")?[El,n]:[bn,n]},sn=([e,t])=>e===Tn&&(t==="function"||t==="symbol"),xd=(e,t,n,r)=>{const i=(a,l)=>{const s=r.push(a)-1;return n.set(l,s),s},o=a=>{if(n.has(a))return n.get(a);let[l,s]=$t(a);switch(l){case Tn:{let p=a;switch(s){case"bigint":l=Cl,p=a.toString();break;case"function":case"symbol":if(e)throw new TypeError("unable to serialize "+s);p=null;break;case"undefined":return i([_l],a)}return i([l,p],a)}case Ht:{if(s){let f=a;return s==="DataView"?f=new Uint8Array(a.buffer):s==="ArrayBuffer"&&(f=new Uint8Array(a)),i([s,[...f]],a)}const p=[],c=i([l,p],a);for(const f of a)p.push(o(f));return c}case bn:{if(s)switch(s){case"BigInt":return i([s,a.toString()],a);case"Boolean":case"Number":case"String":return i([s,a.valueOf()],a)}if(t&&"toJSON"in a)return o(a.toJSON());const p=[],c=i([l,p],a);for(const f of bd(a))(e||!sn($t(a[f])))&&p.push([o(f),o(a[f])]);return c}case Ii:return i([l,a.toISOString()],a);case ji:{const{source:p,flags:c}=a;return i([l,{source:p,flags:c}],a)}case Ri:{const p=[],c=i([l,p],a);for(const[f,d]of a)(e||!(sn($t(f))||sn($t(d))))&&p.push([o(f),o(d)]);return c}case Oi:{const p=[],c=i([l,p],a);for(const f of a)(e||!sn($t(f)))&&p.push(o(f));return c}}const{message:u}=a;return i([l,{name:s,message:u}],a)};return o},ka=(e,{json:t,lossy:n}={})=>{const r=[];return xd(!(t||n),!!t,new Map,r)(e),r},xn=typeof structuredClone=="function"?(e,t)=>t&&("json"in t||"lossy"in t)?xa(ka(e,t)):structuredClone(e):(e,t)=>xa(ka(e,t));function kd(e,t){const n=[{type:"text",value:"↩"}];return t>1&&n.push({type:"element",tagName:"sup",properties:{},children:[{type:"text",value:String(t)}]}),n}function vd(e,t){return"Back to reference "+(e+1)+(t>1?"-"+t:"")}function wd(e){const t=typeof e.options.clobberPrefix=="string"?e.options.clobberPrefix:"user-content-",n=e.options.footnoteBackContent||kd,r=e.options.footnoteBackLabel||vd,i=e.options.footnoteLabel||"Footnotes",o=e.options.footnoteLabelTagName||"h2",a=e.options.footnoteLabelProperties||{className:["sr-only"]},l=[];let s=-1;for(;++s0&&g.push({type:"text",value:" "});let v=typeof n=="string"?n:n(s,d);typeof v=="string"&&(v={type:"text",value:v}),g.push({type:"element",tagName:"a",properties:{href:"#"+t+"fnref-"+f+(d>1?"-"+d:""),dataFootnoteBackref:"",ariaLabel:typeof r=="string"?r:r(s,d),className:["data-footnote-backref"]},children:Array.isArray(v)?v:[v]})}const S=p[p.length-1];if(S&&S.type==="element"&&S.tagName==="p"){const v=S.children[S.children.length-1];v&&v.type==="text"?v.value+=" ":S.children.push({type:"text",value:" "}),S.children.push(...g)}else p.push(...g);const x={type:"element",tagName:"li",properties:{id:t+"fn-"+f},children:e.wrap(p,!0)};e.patch(u,x),l.push(x)}if(l.length!==0)return{type:"element",tagName:"section",properties:{dataFootnotes:!0,className:["footnotes"]},children:[{type:"element",tagName:o,properties:{...xn(a),id:"footnote-label"},children:[{type:"text",value:i}]},{type:"text",value:`
+`});const u={type:"element",tagName:"li",properties:o,children:a};return e.patch(t,u),e.applyData(t,u)}function id(e){let t=!1;if(e.type==="list"){t=e.spread||!1;const n=e.children;let r=-1;for(;!t&&++r1}function ad(e,t){const n={},r=e.all(t);let i=-1;for(typeof t.start=="number"&&t.start!==1&&(n.start=t.start);++i0){const a={type:"element",tagName:"tbody",properties:{},children:e.wrap(n,!0)},l=_i(t.children[1]),s=nl(t.children[t.children.length-1]);l&&s&&(a.position={start:l,end:s}),i.push(a)}const o={type:"element",tagName:"table",properties:{},children:e.wrap(i,!0)};return e.patch(t,o),e.applyData(t,o)}function cd(e,t,n){const r=n?n.children:void 0,o=(r?r.indexOf(t):1)===0?"th":"td",a=n&&n.type==="table"?n.align:void 0,l=a?a.length:t.children.length;let s=-1;const u=[];for(;++s0,!0),r[0]),i=r.index+r[0].length,r=n.exec(t);return o.push(ba(t.slice(i),i>0,!1)),o.join("")}function ba(e,t,n){let r=0,i=e.length;if(t){let o=e.codePointAt(r);for(;o===ga||o===ma;)r++,o=e.codePointAt(r)}if(n){let o=e.codePointAt(i-1);for(;o===ga||o===ma;)i--,o=e.codePointAt(i-1)}return i>r?e.slice(r,i):""}function fd(e,t){const n={type:"text",value:dd(String(t.value))};return e.patch(t,n),e.applyData(t,n)}function hd(e,t){const n={type:"element",tagName:"hr",properties:{},children:[]};return e.patch(t,n),e.applyData(t,n)}const gd={blockquote:Hp,break:Wp,code:Vp,delete:Gp,emphasis:Zp,footnoteReference:Xp,heading:Kp,html:Yp,imageReference:Qp,image:Jp,inlineCode:ed,linkReference:td,link:nd,listItem:rd,list:ad,paragraph:od,root:ld,strong:sd,table:ud,tableCell:pd,tableRow:cd,text:fd,thematicBreak:hd,toml:ln,yaml:ln,definition:ln,footnoteDefinition:ln};function ln(){}const _l=-1,Tn=0,Ht=1,yn=2,Ii=3,ji=4,Ri=5,Oi=6,El=7,Cl=8,ya=typeof self=="object"?self:globalThis,md=(e,t)=>{const n=(i,o)=>(e.set(o,i),i),r=i=>{if(e.has(i))return e.get(i);const[o,a]=t[i];switch(o){case Tn:case _l:return n(a,i);case Ht:{const l=n([],i);for(const s of a)l.push(r(s));return l}case yn:{const l=n({},i);for(const[s,u]of a)l[r(s)]=r(u);return l}case Ii:return n(new Date(a),i);case ji:{const{source:l,flags:s}=a;return n(new RegExp(l,s),i)}case Ri:{const l=n(new Map,i);for(const[s,u]of a)l.set(r(s),r(u));return l}case Oi:{const l=n(new Set,i);for(const s of a)l.add(r(s));return l}case El:{const{name:l,message:s}=a;return n(new ya[l](s),i)}case Cl:return n(BigInt(a),i);case"BigInt":return n(Object(BigInt(a)),i);case"ArrayBuffer":return n(new Uint8Array(a).buffer,a);case"DataView":{const{buffer:l}=new Uint8Array(a);return n(new DataView(l),a)}}return n(new ya[o](a),i)};return r},xa=e=>md(new Map,e)(0),Ct="",{toString:bd}={},{keys:yd}=Object,$t=e=>{const t=typeof e;if(t!=="object"||!e)return[Tn,t];const n=bd.call(e).slice(8,-1);switch(n){case"Array":return[Ht,Ct];case"Object":return[yn,Ct];case"Date":return[Ii,Ct];case"RegExp":return[ji,Ct];case"Map":return[Ri,Ct];case"Set":return[Oi,Ct];case"DataView":return[Ht,n]}return n.includes("Array")?[Ht,n]:n.includes("Error")?[El,n]:[yn,n]},sn=([e,t])=>e===Tn&&(t==="function"||t==="symbol"),xd=(e,t,n,r)=>{const i=(a,l)=>{const s=r.push(a)-1;return n.set(l,s),s},o=a=>{if(n.has(a))return n.get(a);let[l,s]=$t(a);switch(l){case Tn:{let p=a;switch(s){case"bigint":l=Cl,p=a.toString();break;case"function":case"symbol":if(e)throw new TypeError("unable to serialize "+s);p=null;break;case"undefined":return i([_l],a)}return i([l,p],a)}case Ht:{if(s){let f=a;return s==="DataView"?f=new Uint8Array(a.buffer):s==="ArrayBuffer"&&(f=new Uint8Array(a)),i([s,[...f]],a)}const p=[],c=i([l,p],a);for(const f of a)p.push(o(f));return c}case yn:{if(s)switch(s){case"BigInt":return i([s,a.toString()],a);case"Boolean":case"Number":case"String":return i([s,a.valueOf()],a)}if(t&&"toJSON"in a)return o(a.toJSON());const p=[],c=i([l,p],a);for(const f of yd(a))(e||!sn($t(a[f])))&&p.push([o(f),o(a[f])]);return c}case Ii:return i([l,a.toISOString()],a);case ji:{const{source:p,flags:c}=a;return i([l,{source:p,flags:c}],a)}case Ri:{const p=[],c=i([l,p],a);for(const[f,d]of a)(e||!(sn($t(f))||sn($t(d))))&&p.push([o(f),o(d)]);return c}case Oi:{const p=[],c=i([l,p],a);for(const f of a)(e||!sn($t(f)))&&p.push(o(f));return c}}const{message:u}=a;return i([l,{name:s,message:u}],a)};return o},ka=(e,{json:t,lossy:n}={})=>{const r=[];return xd(!(t||n),!!t,new Map,r)(e),r},xn=typeof structuredClone=="function"?(e,t)=>t&&("json"in t||"lossy"in t)?xa(ka(e,t)):structuredClone(e):(e,t)=>xa(ka(e,t));function kd(e,t){const n=[{type:"text",value:"↩"}];return t>1&&n.push({type:"element",tagName:"sup",properties:{},children:[{type:"text",value:String(t)}]}),n}function vd(e,t){return"Back to reference "+(e+1)+(t>1?"-"+t:"")}function wd(e){const t=typeof e.options.clobberPrefix=="string"?e.options.clobberPrefix:"user-content-",n=e.options.footnoteBackContent||kd,r=e.options.footnoteBackLabel||vd,i=e.options.footnoteLabel||"Footnotes",o=e.options.footnoteLabelTagName||"h2",a=e.options.footnoteLabelProperties||{className:["sr-only"]},l=[];let s=-1;for(;++s0&&g.push({type:"text",value:" "});let v=typeof n=="string"?n:n(s,d);typeof v=="string"&&(v={type:"text",value:v}),g.push({type:"element",tagName:"a",properties:{href:"#"+t+"fnref-"+f+(d>1?"-"+d:""),dataFootnoteBackref:"",ariaLabel:typeof r=="string"?r:r(s,d),className:["data-footnote-backref"]},children:Array.isArray(v)?v:[v]})}const S=p[p.length-1];if(S&&S.type==="element"&&S.tagName==="p"){const v=S.children[S.children.length-1];v&&v.type==="text"?v.value+=" ":S.children.push({type:"text",value:" "}),S.children.push(...g)}else p.push(...g);const x={type:"element",tagName:"li",properties:{id:t+"fn-"+f},children:e.wrap(p,!0)};e.patch(u,x),l.push(x)}if(l.length!==0)return{type:"element",tagName:"section",properties:{dataFootnotes:!0,className:["footnotes"]},children:[{type:"element",tagName:o,properties:{...xn(a),id:"footnote-label"},children:[{type:"text",value:i}]},{type:"text",value:`
`},{type:"element",tagName:"ol",properties:{},children:e.wrap(l,!0)},{type:"text",value:`
`}]}}const An=(function(e){if(e==null)return Cd;if(typeof e=="function")return Ln(e);if(typeof e=="object")return Array.isArray(e)?Sd(e):_d(e);if(typeof e=="string")return Ed(e);throw new Error("Expected function, string, or object as test")});function Sd(e){const t=[];let n=-1;for(;++n":""))+")"})}return f;function f(){let d=Tl,g,k,S;if((!t||o(s,u,p[p.length-1]||void 0))&&(d=Nd(n(s,p)),d[0]===ui))return d;if("children"in s&&s.children){const x=s;if(x.children&&d[0]!==Ld)for(k=(r?x.children.length:-1)+a,S=p.concat(x);k>-1&&k0&&n.push({type:"text",value:`
`}),n}function va(e){let t=0,n=e.charCodeAt(t);for(;n===9||n===32;)t++,n=e.charCodeAt(t);return e.slice(t)}function wa(e,t){const n=jd(e,t),r=n.one(e,void 0),i=wd(n),o=Array.isArray(r)?{type:"root",children:r}:r||{type:"root",children:[]};return i&&o.children.push({type:"text",value:`
-`},i),o}function Fd(e,t){return e&&"run"in e?async function(n,r){const i=wa(n,{file:r,...t});await e.run(i,r)}:function(n,r){return wa(n,{file:r,...e||t})}}function Sa(e){if(e)throw e}var $n,_a;function zd(){if(_a)return $n;_a=1;var e=Object.prototype.hasOwnProperty,t=Object.prototype.toString,n=Object.defineProperty,r=Object.getOwnPropertyDescriptor,i=function(u){return typeof Array.isArray=="function"?Array.isArray(u):t.call(u)==="[object Array]"},o=function(u){if(!u||t.call(u)!=="[object Object]")return!1;var p=e.call(u,"constructor"),c=u.constructor&&u.constructor.prototype&&e.call(u.constructor.prototype,"isPrototypeOf");if(u.constructor&&!p&&!c)return!1;var f;for(f in u);return typeof f>"u"||e.call(u,f)},a=function(u,p){n&&p.name==="__proto__"?n(u,p.name,{enumerable:!0,configurable:!0,value:p.newValue,writable:!0}):u[p.name]=p.newValue},l=function(u,p){if(p==="__proto__")if(e.call(u,p)){if(r)return r(u,p).value}else return;return u[p]};return $n=function s(){var u,p,c,f,d,g,k=arguments[0],S=1,x=arguments.length,v=!1;for(typeof k=="boolean"&&(v=k,k=arguments[1]||{},S=2),(k==null||typeof k!="object"&&typeof k!="function")&&(k={});Sa.length;let s;l&&a.push(i);try{s=e.apply(this,a)}catch(u){const p=u;if(l&&n)throw p;return i(p)}l||(s&&s.then&&typeof s.then=="function"?s.then(o,i):s instanceof Error?i(s):o(s))}function i(a,...l){n||(n=!0,t(a,...l))}function o(a){i(null,a)}}const et={basename:qd,dirname:Ud,extname:Hd,join:Wd,sep:"/"};function qd(e,t){if(t!==void 0&&typeof t!="string")throw new TypeError('"ext" argument must be a string');Jt(e);let n=0,r=-1,i=e.length,o;if(t===void 0||t.length===0||t.length>e.length){for(;i--;)if(e.codePointAt(i)===47){if(o){n=i+1;break}}else r<0&&(o=!0,r=i+1);return r<0?"":e.slice(n,r)}if(t===e)return"";let a=-1,l=t.length-1;for(;i--;)if(e.codePointAt(i)===47){if(o){n=i+1;break}}else a<0&&(o=!0,a=i+1),l>-1&&(e.codePointAt(i)===t.codePointAt(l--)?l<0&&(r=i):(l=-1,r=a));return n===r?r=a:r<0&&(r=e.length),e.slice(n,r)}function Ud(e){if(Jt(e),e.length===0)return".";let t=-1,n=e.length,r;for(;--n;)if(e.codePointAt(n)===47){if(r){t=n;break}}else r||(r=!0);return t<0?e.codePointAt(0)===47?"/":".":t===1&&e.codePointAt(0)===47?"//":e.slice(0,t)}function Hd(e){Jt(e);let t=e.length,n=-1,r=0,i=-1,o=0,a;for(;t--;){const l=e.codePointAt(t);if(l===47){if(a){r=t+1;break}continue}n<0&&(a=!0,n=t+1),l===46?i<0?i=t:o!==1&&(o=1):i>-1&&(o=-1)}return i<0||n<0||o===0||o===1&&i===n-1&&i===r+1?"":e.slice(i,n)}function Wd(...e){let t=-1,n;for(;++t0&&e.codePointAt(e.length-1)===47&&(n+="/"),t?"/"+n:n}function Gd(e,t){let n="",r=0,i=-1,o=0,a=-1,l,s;for(;++a<=e.length;){if(a2){if(s=n.lastIndexOf("/"),s!==n.length-1){s<0?(n="",r=0):(n=n.slice(0,s),r=n.length-1-n.lastIndexOf("/")),i=a,o=0;continue}}else if(n.length>0){n="",r=0,i=a,o=0;continue}}t&&(n=n.length>0?n+"/..":"..",r=2)}else n.length>0?n+="/"+e.slice(i+1,a):n=e.slice(i+1,a),r=a-i-1;i=a,o=0}else l===46&&o>-1?o++:o=-1}return n}function Jt(e){if(typeof e!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}const Zd={cwd:Xd};function Xd(){return"/"}function di(e){return!!(e!==null&&typeof e=="object"&&"href"in e&&e.href&&"protocol"in e&&e.protocol&&e.auth===void 0)}function Kd(e){if(typeof e=="string")e=new URL(e);else if(!di(e)){const t=new TypeError('The "path" argument must be of type string or an instance of URL. Received `'+e+"`");throw t.code="ERR_INVALID_ARG_TYPE",t}if(e.protocol!=="file:"){const t=new TypeError("The URL must be of scheme file");throw t.code="ERR_INVALID_URL_SCHEME",t}return Yd(e)}function Yd(e){if(e.hostname!==""){const r=new TypeError('File URL host must be "localhost" or empty on darwin');throw r.code="ERR_INVALID_FILE_URL_HOST",r}const t=e.pathname;let n=-1;for(;++n0){let[d,...g]=p;const k=r[f][1];pi(k)&&pi(d)&&(d=qn(!0,k,d)),r[f]=[u,d,...g]}}}}const tf=new Mi().freeze();function Vn(e,t){if(typeof t!="function")throw new TypeError("Cannot `"+e+"` without `parser`")}function Gn(e,t){if(typeof t!="function")throw new TypeError("Cannot `"+e+"` without `compiler`")}function Zn(e,t){if(t)throw new Error("Cannot call `"+e+"` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.")}function Ca(e){if(!pi(e)||typeof e.type!="string")throw new TypeError("Expected node, got `"+e+"`")}function Ta(e,t,n){if(!n)throw new Error("`"+e+"` finished async. Use `"+t+"` instead")}function un(e){return nf(e)?e:new Ll(e)}function nf(e){return!!(e&&typeof e=="object"&&"message"in e&&"messages"in e)}function rf(e){return typeof e=="string"||af(e)}function af(e){return!!(e&&typeof e=="object"&&"byteLength"in e&&"byteOffset"in e)}const of="https://github.com/remarkjs/react-markdown/blob/main/changelog.md",Aa=[],La={allowDangerousHtml:!0},lf=/^(https?|ircs?|mailto|xmpp)$/i,sf=[{from:"astPlugins",id:"remove-buggy-html-in-markdown-parser"},{from:"allowDangerousHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"allowNode",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowElement"},{from:"allowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowedElements"},{from:"className",id:"remove-classname"},{from:"disallowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"disallowedElements"},{from:"escapeHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"includeElementIndex",id:"#remove-includeelementindex"},{from:"includeNodeIndex",id:"change-includenodeindex-to-includeelementindex"},{from:"linkTarget",id:"remove-linktarget"},{from:"plugins",id:"change-plugins-to-remarkplugins",to:"remarkPlugins"},{from:"rawSourcePos",id:"#remove-rawsourcepos"},{from:"renderers",id:"change-renderers-to-components",to:"components"},{from:"source",id:"change-source-to-children",to:"children"},{from:"sourcePos",id:"#remove-sourcepos"},{from:"transformImageUri",id:"#add-urltransform",to:"urlTransform"},{from:"transformLinkUri",id:"#add-urltransform",to:"urlTransform"}];function uf(e){const t=cf(e),n=pf(e);return df(t.runSync(t.parse(n),n),e)}function cf(e){const t=e.rehypePlugins||Aa,n=e.remarkPlugins||Aa,r=e.remarkRehypeOptions?{...e.remarkRehypeOptions,...La}:La;return tf().use(Up).use(n).use(Fd,r).use(t)}function pf(e){const t=e.children||"",n=new Ll;return typeof t=="string"&&(n.value=t),n}function df(e,t){const n=t.allowedElements,r=t.allowElement,i=t.components,o=t.disallowedElements,a=t.skipHtml,l=t.unwrapDisallowed,s=t.urlTransform||ff;for(const p of sf)Object.hasOwn(t,p.from)&&(""+p.from+(p.to?"use `"+p.to+"` instead":"remove it")+of+p.id,void 0);return Di(e,u),Cu(e,{Fragment:h.Fragment,components:i,ignoreInvalidStyle:!0,jsx:h.jsx,jsxs:h.jsxs,passKeys:!0,passNode:!0});function u(p,c,f){if(p.type==="raw"&&f&&typeof c=="number")return a?f.children.splice(c,1):f.children[c]={type:"text",value:p.value},c;if(p.type==="element"){let d;for(d in zn)if(Object.hasOwn(zn,d)&&Object.hasOwn(p.properties,d)){const g=p.properties[d],k=zn[d];(k===null||k.includes(p.tagName))&&(p.properties[d]=s(String(g||""),d,p))}}if(p.type==="element"){let d=n?!n.includes(p.tagName):o?o.includes(p.tagName):!1;if(!d&&r&&typeof c=="number"&&(d=!r(p,c,f)),d&&f&&typeof c=="number")return l&&p.children?f.children.splice(c,1,...p.children):f.children.splice(c,1),c}}}function ff(e){const t=e.indexOf(":"),n=e.indexOf("?"),r=e.indexOf("#"),i=e.indexOf("/");return t===-1||i!==-1&&t>i||n!==-1&&t>n||r!==-1&&t>r||lf.test(e.slice(0,t))?e:""}function Na(e,t){const n=String(e);if(typeof t!="string")throw new TypeError("Expected character");let r=0,i=n.indexOf(t);for(;i!==-1;)r++,i=n.indexOf(t,i+t.length);return r}function hf(e){if(typeof e!="string")throw new TypeError("Expected a string");return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}function gf(e,t,n){const i=An((n||{}).ignore||[]),o=mf(t);let a=-1;for(;++a0?{type:"text",value:m}:void 0),m===!1?f.lastIndex=_+1:(g!==_&&v.push({type:"text",value:u.value.slice(g,_)}),Array.isArray(m)?v.push(...m):m&&v.push(m),g=_+y[0].length,x=!0),!f.global)break;y=f.exec(u.value)}return x?(g?\]}]+$/.exec(e);if(!t)return[e,void 0];e=e.slice(0,t.index);let n=t[0],r=n.indexOf(")");const i=Na(e,"(");let o=Na(e,")");for(;r!==-1&&i>o;)e+=n.slice(0,r+1),n=n.slice(r+1),r=n.indexOf(")"),o++;return[e,n]}function If(e,t){const n=e.input.charCodeAt(e.index-1);return(e.index===0||kt(n)||En(n))&&!0}Nl.peek=Bf;function jf(){this.buffer()}function Rf(e){this.enter({type:"footnoteReference",identifier:"",label:""},e)}function Of(){this.buffer()}function Df(e){this.enter({type:"footnoteDefinition",identifier:"",label:"",children:[]},e)}function Mf(e){const t=this.resume(),n=this.stack[this.stack.length-1];n.type,n.identifier=Ke(this.sliceSerialize(e)).toLowerCase(),n.label=t}function Ff(e){this.exit(e)}function zf(e){const t=this.resume(),n=this.stack[this.stack.length-1];n.type,n.identifier=Ke(this.sliceSerialize(e)).toLowerCase(),n.label=t}function Pf(e){this.exit(e)}function Bf(){return"["}function Nl(e,t,n,r){const i=n.createTracker(r);let o=i.move("[^");const a=n.enter("footnoteReference"),l=n.enter("reference");return o+=i.move(n.safe(n.associationId(e),{after:"]",before:o})),l(),a(),o+=i.move("]"),o}function $f(){return{enter:{gfmFootnoteCallString:jf,gfmFootnoteCall:Rf,gfmFootnoteDefinitionLabelString:Of,gfmFootnoteDefinition:Df},exit:{gfmFootnoteCallString:Mf,gfmFootnoteCall:Ff,gfmFootnoteDefinitionLabelString:zf,gfmFootnoteDefinition:Pf}}}function qf(e){let t=!1;return e&&e.firstLineBlank&&(t=!0),{handlers:{footnoteDefinition:n,footnoteReference:Nl},unsafe:[{character:"[",inConstruct:["label","phrasing","reference"]}]};function n(r,i,o,a){const l=o.createTracker(a);let s=l.move("[^");const u=o.enter("footnoteDefinition"),p=o.enter("label");return s+=l.move(o.safe(o.associationId(r),{before:s,after:"]"})),p(),s+=l.move("]:"),r.children&&r.children.length>0&&(l.shift(4),s+=l.move((t?`
-`:" ")+o.indentLines(o.containerFlow(r,l.current()),t?Il:Uf))),u(),s}}function Uf(e,t,n){return t===0?e:Il(e,t,n)}function Il(e,t,n){return(n?"":" ")+e}const Hf=["autolink","destinationLiteral","destinationRaw","reference","titleQuote","titleApostrophe"];jl.peek=Xf;function Wf(){return{canContainEols:["delete"],enter:{strikethrough:Gf},exit:{strikethrough:Zf}}}function Vf(){return{unsafe:[{character:"~",inConstruct:"phrasing",notInConstruct:Hf}],handlers:{delete:jl}}}function Gf(e){this.enter({type:"delete",children:[]},e)}function Zf(e){this.exit(e)}function jl(e,t,n,r){const i=n.createTracker(r),o=n.enter("strikethrough");let a=i.move("~~");return a+=n.containerPhrasing(e,{...i.current(),before:a,after:"~"}),a+=i.move("~~"),o(),a}function Xf(){return"~"}function Kf(e){return e.length}function Yf(e,t){const n=t||{},r=(n.align||[]).concat(),i=n.stringLength||Kf,o=[],a=[],l=[],s=[];let u=0,p=-1;for(;++pu&&(u=e[p].length);++xs[x])&&(s[x]=y)}k.push(v)}a[p]=k,l[p]=S}let c=-1;if(typeof r=="object"&&"length"in r)for(;++cs[c]&&(s[c]=v),d[c]=v),f[c]=y}a.splice(1,0,f),l.splice(1,0,d),p=-1;const g=[];for(;++p"u"||e.call(u,f)},a=function(u,p){n&&p.name==="__proto__"?n(u,p.name,{enumerable:!0,configurable:!0,value:p.newValue,writable:!0}):u[p.name]=p.newValue},l=function(u,p){if(p==="__proto__")if(e.call(u,p)){if(r)return r(u,p).value}else return;return u[p]};return $n=function s(){var u,p,c,f,d,g,k=arguments[0],S=1,x=arguments.length,v=!1;for(typeof k=="boolean"&&(v=k,k=arguments[1]||{},S=2),(k==null||typeof k!="object"&&typeof k!="function")&&(k={});Sa.length;let s;l&&a.push(i);try{s=e.apply(this,a)}catch(u){const p=u;if(l&&n)throw p;return i(p)}l||(s&&s.then&&typeof s.then=="function"?s.then(o,i):s instanceof Error?i(s):o(s))}function i(a,...l){n||(n=!0,t(a,...l))}function o(a){i(null,a)}}const et={basename:qd,dirname:Ud,extname:Hd,join:Wd,sep:"/"};function qd(e,t){if(t!==void 0&&typeof t!="string")throw new TypeError('"ext" argument must be a string');Jt(e);let n=0,r=-1,i=e.length,o;if(t===void 0||t.length===0||t.length>e.length){for(;i--;)if(e.codePointAt(i)===47){if(o){n=i+1;break}}else r<0&&(o=!0,r=i+1);return r<0?"":e.slice(n,r)}if(t===e)return"";let a=-1,l=t.length-1;for(;i--;)if(e.codePointAt(i)===47){if(o){n=i+1;break}}else a<0&&(o=!0,a=i+1),l>-1&&(e.codePointAt(i)===t.codePointAt(l--)?l<0&&(r=i):(l=-1,r=a));return n===r?r=a:r<0&&(r=e.length),e.slice(n,r)}function Ud(e){if(Jt(e),e.length===0)return".";let t=-1,n=e.length,r;for(;--n;)if(e.codePointAt(n)===47){if(r){t=n;break}}else r||(r=!0);return t<0?e.codePointAt(0)===47?"/":".":t===1&&e.codePointAt(0)===47?"//":e.slice(0,t)}function Hd(e){Jt(e);let t=e.length,n=-1,r=0,i=-1,o=0,a;for(;t--;){const l=e.codePointAt(t);if(l===47){if(a){r=t+1;break}continue}n<0&&(a=!0,n=t+1),l===46?i<0?i=t:o!==1&&(o=1):i>-1&&(o=-1)}return i<0||n<0||o===0||o===1&&i===n-1&&i===r+1?"":e.slice(i,n)}function Wd(...e){let t=-1,n;for(;++t0&&e.codePointAt(e.length-1)===47&&(n+="/"),t?"/"+n:n}function Gd(e,t){let n="",r=0,i=-1,o=0,a=-1,l,s;for(;++a<=e.length;){if(a2){if(s=n.lastIndexOf("/"),s!==n.length-1){s<0?(n="",r=0):(n=n.slice(0,s),r=n.length-1-n.lastIndexOf("/")),i=a,o=0;continue}}else if(n.length>0){n="",r=0,i=a,o=0;continue}}t&&(n=n.length>0?n+"/..":"..",r=2)}else n.length>0?n+="/"+e.slice(i+1,a):n=e.slice(i+1,a),r=a-i-1;i=a,o=0}else l===46&&o>-1?o++:o=-1}return n}function Jt(e){if(typeof e!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}const Zd={cwd:Xd};function Xd(){return"/"}function di(e){return!!(e!==null&&typeof e=="object"&&"href"in e&&e.href&&"protocol"in e&&e.protocol&&e.auth===void 0)}function Kd(e){if(typeof e=="string")e=new URL(e);else if(!di(e)){const t=new TypeError('The "path" argument must be of type string or an instance of URL. Received `'+e+"`");throw t.code="ERR_INVALID_ARG_TYPE",t}if(e.protocol!=="file:"){const t=new TypeError("The URL must be of scheme file");throw t.code="ERR_INVALID_URL_SCHEME",t}return Yd(e)}function Yd(e){if(e.hostname!==""){const r=new TypeError('File URL host must be "localhost" or empty on darwin');throw r.code="ERR_INVALID_FILE_URL_HOST",r}const t=e.pathname;let n=-1;for(;++n0){let[d,...g]=p;const k=r[f][1];pi(k)&&pi(d)&&(d=qn(!0,k,d)),r[f]=[u,d,...g]}}}}const tf=new Mi().freeze();function Vn(e,t){if(typeof t!="function")throw new TypeError("Cannot `"+e+"` without `parser`")}function Gn(e,t){if(typeof t!="function")throw new TypeError("Cannot `"+e+"` without `compiler`")}function Zn(e,t){if(t)throw new Error("Cannot call `"+e+"` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.")}function Ca(e){if(!pi(e)||typeof e.type!="string")throw new TypeError("Expected node, got `"+e+"`")}function Ta(e,t,n){if(!n)throw new Error("`"+e+"` finished async. Use `"+t+"` instead")}function un(e){return nf(e)?e:new Ll(e)}function nf(e){return!!(e&&typeof e=="object"&&"message"in e&&"messages"in e)}function rf(e){return typeof e=="string"||af(e)}function af(e){return!!(e&&typeof e=="object"&&"byteLength"in e&&"byteOffset"in e)}const of="https://github.com/remarkjs/react-markdown/blob/main/changelog.md",Aa=[],La={allowDangerousHtml:!0},lf=/^(https?|ircs?|mailto|xmpp)$/i,sf=[{from:"astPlugins",id:"remove-buggy-html-in-markdown-parser"},{from:"allowDangerousHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"allowNode",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowElement"},{from:"allowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowedElements"},{from:"className",id:"remove-classname"},{from:"disallowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"disallowedElements"},{from:"escapeHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"includeElementIndex",id:"#remove-includeelementindex"},{from:"includeNodeIndex",id:"change-includenodeindex-to-includeelementindex"},{from:"linkTarget",id:"remove-linktarget"},{from:"plugins",id:"change-plugins-to-remarkplugins",to:"remarkPlugins"},{from:"rawSourcePos",id:"#remove-rawsourcepos"},{from:"renderers",id:"change-renderers-to-components",to:"components"},{from:"source",id:"change-source-to-children",to:"children"},{from:"sourcePos",id:"#remove-sourcepos"},{from:"transformImageUri",id:"#add-urltransform",to:"urlTransform"},{from:"transformLinkUri",id:"#add-urltransform",to:"urlTransform"}];function uf(e){const t=cf(e),n=pf(e);return df(t.runSync(t.parse(n),n),e)}function cf(e){const t=e.rehypePlugins||Aa,n=e.remarkPlugins||Aa,r=e.remarkRehypeOptions?{...e.remarkRehypeOptions,...La}:La;return tf().use(Up).use(n).use(Fd,r).use(t)}function pf(e){const t=e.children||"",n=new Ll;return typeof t=="string"&&(n.value=t),n}function df(e,t){const n=t.allowedElements,r=t.allowElement,i=t.components,o=t.disallowedElements,a=t.skipHtml,l=t.unwrapDisallowed,s=t.urlTransform||ff;for(const p of sf)Object.hasOwn(t,p.from)&&(""+p.from+(p.to?"use `"+p.to+"` instead":"remove it")+of+p.id,void 0);return Di(e,u),Cu(e,{Fragment:h.Fragment,components:i,ignoreInvalidStyle:!0,jsx:h.jsx,jsxs:h.jsxs,passKeys:!0,passNode:!0});function u(p,c,f){if(p.type==="raw"&&f&&typeof c=="number")return a?f.children.splice(c,1):f.children[c]={type:"text",value:p.value},c;if(p.type==="element"){let d;for(d in zn)if(Object.hasOwn(zn,d)&&Object.hasOwn(p.properties,d)){const g=p.properties[d],k=zn[d];(k===null||k.includes(p.tagName))&&(p.properties[d]=s(String(g||""),d,p))}}if(p.type==="element"){let d=n?!n.includes(p.tagName):o?o.includes(p.tagName):!1;if(!d&&r&&typeof c=="number"&&(d=!r(p,c,f)),d&&f&&typeof c=="number")return l&&p.children?f.children.splice(c,1,...p.children):f.children.splice(c,1),c}}}function ff(e){const t=e.indexOf(":"),n=e.indexOf("?"),r=e.indexOf("#"),i=e.indexOf("/");return t===-1||i!==-1&&t>i||n!==-1&&t>n||r!==-1&&t>r||lf.test(e.slice(0,t))?e:""}function Na(e,t){const n=String(e);if(typeof t!="string")throw new TypeError("Expected character");let r=0,i=n.indexOf(t);for(;i!==-1;)r++,i=n.indexOf(t,i+t.length);return r}function hf(e){if(typeof e!="string")throw new TypeError("Expected a string");return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}function gf(e,t,n){const i=An((n||{}).ignore||[]),o=mf(t);let a=-1;for(;++a0?{type:"text",value:m}:void 0),m===!1?f.lastIndex=_+1:(g!==_&&v.push({type:"text",value:u.value.slice(g,_)}),Array.isArray(m)?v.push(...m):m&&v.push(m),g=_+b[0].length,x=!0),!f.global)break;b=f.exec(u.value)}return x?(g?\]}]+$/.exec(e);if(!t)return[e,void 0];e=e.slice(0,t.index);let n=t[0],r=n.indexOf(")");const i=Na(e,"(");let o=Na(e,")");for(;r!==-1&&i>o;)e+=n.slice(0,r+1),n=n.slice(r+1),r=n.indexOf(")"),o++;return[e,n]}function If(e,t){const n=e.input.charCodeAt(e.index-1);return(e.index===0||kt(n)||En(n))&&!0}Nl.peek=Bf;function jf(){this.buffer()}function Rf(e){this.enter({type:"footnoteReference",identifier:"",label:""},e)}function Of(){this.buffer()}function Df(e){this.enter({type:"footnoteDefinition",identifier:"",label:"",children:[]},e)}function Mf(e){const t=this.resume(),n=this.stack[this.stack.length-1];n.type,n.identifier=Ke(this.sliceSerialize(e)).toLowerCase(),n.label=t}function Ff(e){this.exit(e)}function zf(e){const t=this.resume(),n=this.stack[this.stack.length-1];n.type,n.identifier=Ke(this.sliceSerialize(e)).toLowerCase(),n.label=t}function Pf(e){this.exit(e)}function Bf(){return"["}function Nl(e,t,n,r){const i=n.createTracker(r);let o=i.move("[^");const a=n.enter("footnoteReference"),l=n.enter("reference");return o+=i.move(n.safe(n.associationId(e),{after:"]",before:o})),l(),a(),o+=i.move("]"),o}function $f(){return{enter:{gfmFootnoteCallString:jf,gfmFootnoteCall:Rf,gfmFootnoteDefinitionLabelString:Of,gfmFootnoteDefinition:Df},exit:{gfmFootnoteCallString:Mf,gfmFootnoteCall:Ff,gfmFootnoteDefinitionLabelString:zf,gfmFootnoteDefinition:Pf}}}function qf(e){let t=!1;return e&&e.firstLineBlank&&(t=!0),{handlers:{footnoteDefinition:n,footnoteReference:Nl},unsafe:[{character:"[",inConstruct:["label","phrasing","reference"]}]};function n(r,i,o,a){const l=o.createTracker(a);let s=l.move("[^");const u=o.enter("footnoteDefinition"),p=o.enter("label");return s+=l.move(o.safe(o.associationId(r),{before:s,after:"]"})),p(),s+=l.move("]:"),r.children&&r.children.length>0&&(l.shift(4),s+=l.move((t?`
+`:" ")+o.indentLines(o.containerFlow(r,l.current()),t?Il:Uf))),u(),s}}function Uf(e,t,n){return t===0?e:Il(e,t,n)}function Il(e,t,n){return(n?"":" ")+e}const Hf=["autolink","destinationLiteral","destinationRaw","reference","titleQuote","titleApostrophe"];jl.peek=Xf;function Wf(){return{canContainEols:["delete"],enter:{strikethrough:Gf},exit:{strikethrough:Zf}}}function Vf(){return{unsafe:[{character:"~",inConstruct:"phrasing",notInConstruct:Hf}],handlers:{delete:jl}}}function Gf(e){this.enter({type:"delete",children:[]},e)}function Zf(e){this.exit(e)}function jl(e,t,n,r){const i=n.createTracker(r),o=n.enter("strikethrough");let a=i.move("~~");return a+=n.containerPhrasing(e,{...i.current(),before:a,after:"~"}),a+=i.move("~~"),o(),a}function Xf(){return"~"}function Kf(e){return e.length}function Yf(e,t){const n=t||{},r=(n.align||[]).concat(),i=n.stringLength||Kf,o=[],a=[],l=[],s=[];let u=0,p=-1;for(;++pu&&(u=e[p].length);++xs[x])&&(s[x]=b)}k.push(v)}a[p]=k,l[p]=S}let c=-1;if(typeof r=="object"&&"length"in r)for(;++cs[c]&&(s[c]=v),d[c]=v),f[c]=b}a.splice(1,0,f),l.splice(1,0,d),p=-1;const g=[];for(;++p "),o.shift(2);const a=n.indentLines(n.containerFlow(e,o.current()),eh);return i(),a}function eh(e,t,n){return">"+(n?"":" ")+e}function th(e,t){return ja(e,t.inConstruct,!0)&&!ja(e,t.notInConstruct,!1)}function ja(e,t,n){if(typeof t=="string"&&(t=[t]),!t||t.length===0)return n;let r=-1;for(;++ra&&(a=o):o=1,i=r+t.length,r=n.indexOf(t,i);return a}function rh(e,t){return!!(t.options.fences===!1&&e.value&&!e.lang&&/[^ \r\n]/.test(e.value)&&!/^[\t ]*(?:[\r\n]|$)|(?:^|[\r\n])[\t ]*$/.test(e.value))}function ih(e){const t=e.options.fence||"`";if(t!=="`"&&t!=="~")throw new Error("Cannot serialize code with `"+t+"` for `options.fence`, expected `` ` `` or `~`");return t}function ah(e,t,n,r){const i=ih(n),o=e.value||"",a=i==="`"?"GraveAccent":"Tilde";if(rh(e,n)){const c=n.enter("codeIndented"),f=n.indentLines(o,oh);return c(),f}const l=n.createTracker(r),s=i.repeat(Math.max(nh(o,i)+1,3)),u=n.enter("codeFenced");let p=l.move(s);if(e.lang){const c=n.enter(`codeFencedLang${a}`);p+=l.move(n.safe(e.lang,{before:p,after:" ",encode:["`"],...l.current()})),c()}if(e.lang&&e.meta){const c=n.enter(`codeFencedMeta${a}`);p+=l.move(" "),p+=l.move(n.safe(e.meta,{before:p,after:`
@@ -24,16 +24,16 @@ import{g as me,j as h,R as it,c as mn,u as Ye,a as Ft,b as Zo,r as N,d as Gs,e a
`});return c(),p(),f+`
`+(i===1?"=":"-").repeat(f.length-(Math.max(f.lastIndexOf("\r"),f.lastIndexOf(`
`))+1))}const a="#".repeat(i),l=n.enter("headingAtx"),s=n.enter("phrasing");o.move(a+" ");let u=n.containerPhrasing(e,{before:"# ",after:`
-`,...o.current()});return/^[\t ]/.test(u)&&(u=Zt(u.charCodeAt(0))+u.slice(1)),u=u?a+" "+u:a,n.options.closeAtx&&(u+=" "+a),s(),l(),u}Ol.peek=dh;function Ol(e){return e.value||""}function dh(){return"<"}Dl.peek=fh;function Dl(e,t,n,r){const i=Fi(n),o=i==='"'?"Quote":"Apostrophe",a=n.enter("image");let l=n.enter("label");const s=n.createTracker(r);let u=s.move("![");return u+=s.move(n.safe(e.alt,{before:u,after:"]",...s.current()})),u+=s.move("]("),l(),!e.url&&e.title||/[\0- \u007F]/.test(e.url)?(l=n.enter("destinationLiteral"),u+=s.move("<"),u+=s.move(n.safe(e.url,{before:u,after:">",...s.current()})),u+=s.move(">")):(l=n.enter("destinationRaw"),u+=s.move(n.safe(e.url,{before:u,after:e.title?" ":")",...s.current()}))),l(),e.title&&(l=n.enter(`title${o}`),u+=s.move(" "+i),u+=s.move(n.safe(e.title,{before:u,after:i,...s.current()})),u+=s.move(i),l()),u+=s.move(")"),a(),u}function fh(){return"!"}Ml.peek=hh;function Ml(e,t,n,r){const i=e.referenceType,o=n.enter("imageReference");let a=n.enter("label");const l=n.createTracker(r);let s=l.move("![");const u=n.safe(e.alt,{before:s,after:"]",...l.current()});s+=l.move(u+"]["),a();const p=n.stack;n.stack=[],a=n.enter("reference");const c=n.safe(n.associationId(e),{before:s,after:"]",...l.current()});return a(),n.stack=p,o(),i==="full"||!u||u!==c?s+=l.move(c+"]"):i==="shortcut"?s=s.slice(0,-1):s+=l.move("]"),s}function hh(){return"!"}Fl.peek=gh;function Fl(e,t,n){let r=e.value||"",i="`",o=-1;for(;new RegExp("(^|[^`])"+i+"([^`]|$)").test(r);)i+="`";for(/[^ \r\n]/.test(r)&&(/^[ \r\n]/.test(r)&&/[ \r\n]$/.test(r)||/^`|`$/.test(r))&&(r=" "+r+" ");++o\u007F]/.test(e.url))}Pl.peek=mh;function Pl(e,t,n,r){const i=Fi(n),o=i==='"'?"Quote":"Apostrophe",a=n.createTracker(r);let l,s;if(zl(e,n)){const p=n.stack;n.stack=[],l=n.enter("autolink");let c=a.move("<");return c+=a.move(n.containerPhrasing(e,{before:c,after:">",...a.current()})),c+=a.move(">"),l(),n.stack=p,c}l=n.enter("link"),s=n.enter("label");let u=a.move("[");return u+=a.move(n.containerPhrasing(e,{before:u,after:"](",...a.current()})),u+=a.move("]("),s(),!e.url&&e.title||/[\0- \u007F]/.test(e.url)?(s=n.enter("destinationLiteral"),u+=a.move("<"),u+=a.move(n.safe(e.url,{before:u,after:">",...a.current()})),u+=a.move(">")):(s=n.enter("destinationRaw"),u+=a.move(n.safe(e.url,{before:u,after:e.title?" ":")",...a.current()}))),s(),e.title&&(s=n.enter(`title${o}`),u+=a.move(" "+i),u+=a.move(n.safe(e.title,{before:u,after:i,...a.current()})),u+=a.move(i),s()),u+=a.move(")"),l(),u}function mh(e,t,n){return zl(e,n)?"<":"["}Bl.peek=yh;function Bl(e,t,n,r){const i=e.referenceType,o=n.enter("linkReference");let a=n.enter("label");const l=n.createTracker(r);let s=l.move("[");const u=n.containerPhrasing(e,{before:s,after:"]",...l.current()});s+=l.move(u+"]["),a();const p=n.stack;n.stack=[],a=n.enter("reference");const c=n.safe(n.associationId(e),{before:s,after:"]",...l.current()});return a(),n.stack=p,o(),i==="full"||!u||u!==c?s+=l.move(c+"]"):i==="shortcut"?s=s.slice(0,-1):s+=l.move("]"),s}function yh(){return"["}function zi(e){const t=e.options.bullet||"*";if(t!=="*"&&t!=="+"&&t!=="-")throw new Error("Cannot serialize items with `"+t+"` for `options.bullet`, expected `*`, `+`, or `-`");return t}function bh(e){const t=zi(e),n=e.options.bulletOther;if(!n)return t==="*"?"-":"*";if(n!=="*"&&n!=="+"&&n!=="-")throw new Error("Cannot serialize items with `"+n+"` for `options.bulletOther`, expected `*`, `+`, or `-`");if(n===t)throw new Error("Expected `bullet` (`"+t+"`) and `bulletOther` (`"+n+"`) to be different");return n}function xh(e){const t=e.options.bulletOrdered||".";if(t!=="."&&t!==")")throw new Error("Cannot serialize items with `"+t+"` for `options.bulletOrdered`, expected `.` or `)`");return t}function $l(e){const t=e.options.rule||"*";if(t!=="*"&&t!=="-"&&t!=="_")throw new Error("Cannot serialize rules with `"+t+"` for `options.rule`, expected `*`, `-`, or `_`");return t}function kh(e,t,n,r){const i=n.enter("list"),o=n.bulletCurrent;let a=e.ordered?xh(n):zi(n);const l=e.ordered?a==="."?")":".":bh(n);let s=t&&n.bulletLastUsed?a===n.bulletLastUsed:!1;if(!e.ordered){const p=e.children?e.children[0]:void 0;if((a==="*"||a==="-")&&p&&(!p.children||!p.children[0])&&n.stack[n.stack.length-1]==="list"&&n.stack[n.stack.length-2]==="listItem"&&n.stack[n.stack.length-3]==="list"&&n.stack[n.stack.length-4]==="listItem"&&n.indexStack[n.indexStack.length-1]===0&&n.indexStack[n.indexStack.length-2]===0&&n.indexStack[n.indexStack.length-3]===0&&(s=!0),$l(n)===a&&p){let c=-1;for(;++c-1?t.start:1)+(n.options.incrementListMarker===!1?0:t.children.indexOf(e))+o);let a=o.length+1;(i==="tab"||i==="mixed"&&(t&&t.type==="list"&&t.spread||e.spread))&&(a=Math.ceil(a/4)*4);const l=n.createTracker(r);l.move(o+" ".repeat(a-o.length)),l.shift(a);const s=n.enter("listItem"),u=n.indentLines(n.containerFlow(e,l.current()),p);return s(),u;function p(c,f,d){return f?(d?"":" ".repeat(a))+c:(d?o:o+" ".repeat(a-o.length))+c}}function Sh(e,t,n,r){const i=n.enter("paragraph"),o=n.enter("phrasing"),a=n.containerPhrasing(e,r);return o(),i(),a}const _h=An(["break","delete","emphasis","footnote","footnoteReference","image","imageReference","inlineCode","inlineMath","link","linkReference","mdxJsxTextElement","mdxTextExpression","strong","text","textDirective"]);function Eh(e,t,n,r){return(e.children.some(function(a){return _h(a)})?n.containerPhrasing:n.containerFlow).call(n,e,r)}function Ch(e){const t=e.options.strong||"*";if(t!=="*"&&t!=="_")throw new Error("Cannot serialize strong with `"+t+"` for `options.strong`, expected `*`, or `_`");return t}ql.peek=Th;function ql(e,t,n,r){const i=Ch(n),o=n.enter("strong"),a=n.createTracker(r),l=a.move(i+i);let s=a.move(n.containerPhrasing(e,{after:i,before:l,...a.current()}));const u=s.charCodeAt(0),p=kn(r.before.charCodeAt(r.before.length-1),u,i);p.inside&&(s=Zt(u)+s.slice(1));const c=s.charCodeAt(s.length-1),f=kn(r.after.charCodeAt(0),c,i);f.inside&&(s=s.slice(0,-1)+Zt(c));const d=a.move(i+i);return o(),n.attentionEncodeSurroundingInfo={after:f.outside,before:p.outside},l+s+d}function Th(e,t,n){return n.options.strong||"*"}function Ah(e,t,n,r){return n.safe(e.value,r)}function Lh(e){const t=e.options.ruleRepetition||3;if(t<3)throw new Error("Cannot serialize rules with repetition `"+t+"` for `options.ruleRepetition`, expected `3` or more");return t}function Nh(e,t,n){const r=($l(n)+(n.options.ruleSpaces?" ":"")).repeat(Lh(n));return n.options.ruleSpaces?r.slice(0,-1):r}const Ul={blockquote:Jf,break:Ra,code:ah,definition:lh,emphasis:Rl,hardBreak:Ra,heading:ph,html:Ol,image:Dl,imageReference:Ml,inlineCode:Fl,link:Pl,linkReference:Bl,list:kh,listItem:wh,paragraph:Sh,root:Eh,strong:ql,text:Ah,thematicBreak:Nh};function Ih(){return{enter:{table:jh,tableData:Oa,tableHeader:Oa,tableRow:Oh},exit:{codeText:Dh,table:Rh,tableData:Qn,tableHeader:Qn,tableRow:Qn}}}function jh(e){const t=e._align;this.enter({type:"table",align:t.map(function(n){return n==="none"?null:n}),children:[]},e),this.data.inTable=!0}function Rh(e){this.exit(e),this.data.inTable=void 0}function Oh(e){this.enter({type:"tableRow",children:[]},e)}function Qn(e){this.exit(e)}function Oa(e){this.enter({type:"tableCell",children:[]},e)}function Dh(e){let t=this.resume();this.data.inTable&&(t=t.replace(/\\([\\|])/g,Mh));const n=this.stack[this.stack.length-1];n.type,n.value=t,this.exit(e)}function Mh(e,t){return t==="|"?t:e}function Fh(e){const t=e||{},n=t.tableCellPadding,r=t.tablePipeAlign,i=t.stringLength,o=n?" ":"|";return{unsafe:[{character:"\r",inConstruct:"tableCell"},{character:`
+`,...o.current()});return/^[\t ]/.test(u)&&(u=Zt(u.charCodeAt(0))+u.slice(1)),u=u?a+" "+u:a,n.options.closeAtx&&(u+=" "+a),s(),l(),u}Ol.peek=dh;function Ol(e){return e.value||""}function dh(){return"<"}Dl.peek=fh;function Dl(e,t,n,r){const i=Fi(n),o=i==='"'?"Quote":"Apostrophe",a=n.enter("image");let l=n.enter("label");const s=n.createTracker(r);let u=s.move("![");return u+=s.move(n.safe(e.alt,{before:u,after:"]",...s.current()})),u+=s.move("]("),l(),!e.url&&e.title||/[\0- \u007F]/.test(e.url)?(l=n.enter("destinationLiteral"),u+=s.move("<"),u+=s.move(n.safe(e.url,{before:u,after:">",...s.current()})),u+=s.move(">")):(l=n.enter("destinationRaw"),u+=s.move(n.safe(e.url,{before:u,after:e.title?" ":")",...s.current()}))),l(),e.title&&(l=n.enter(`title${o}`),u+=s.move(" "+i),u+=s.move(n.safe(e.title,{before:u,after:i,...s.current()})),u+=s.move(i),l()),u+=s.move(")"),a(),u}function fh(){return"!"}Ml.peek=hh;function Ml(e,t,n,r){const i=e.referenceType,o=n.enter("imageReference");let a=n.enter("label");const l=n.createTracker(r);let s=l.move("![");const u=n.safe(e.alt,{before:s,after:"]",...l.current()});s+=l.move(u+"]["),a();const p=n.stack;n.stack=[],a=n.enter("reference");const c=n.safe(n.associationId(e),{before:s,after:"]",...l.current()});return a(),n.stack=p,o(),i==="full"||!u||u!==c?s+=l.move(c+"]"):i==="shortcut"?s=s.slice(0,-1):s+=l.move("]"),s}function hh(){return"!"}Fl.peek=gh;function Fl(e,t,n){let r=e.value||"",i="`",o=-1;for(;new RegExp("(^|[^`])"+i+"([^`]|$)").test(r);)i+="`";for(/[^ \r\n]/.test(r)&&(/^[ \r\n]/.test(r)&&/[ \r\n]$/.test(r)||/^`|`$/.test(r))&&(r=" "+r+" ");++o\u007F]/.test(e.url))}Pl.peek=mh;function Pl(e,t,n,r){const i=Fi(n),o=i==='"'?"Quote":"Apostrophe",a=n.createTracker(r);let l,s;if(zl(e,n)){const p=n.stack;n.stack=[],l=n.enter("autolink");let c=a.move("<");return c+=a.move(n.containerPhrasing(e,{before:c,after:">",...a.current()})),c+=a.move(">"),l(),n.stack=p,c}l=n.enter("link"),s=n.enter("label");let u=a.move("[");return u+=a.move(n.containerPhrasing(e,{before:u,after:"](",...a.current()})),u+=a.move("]("),s(),!e.url&&e.title||/[\0- \u007F]/.test(e.url)?(s=n.enter("destinationLiteral"),u+=a.move("<"),u+=a.move(n.safe(e.url,{before:u,after:">",...a.current()})),u+=a.move(">")):(s=n.enter("destinationRaw"),u+=a.move(n.safe(e.url,{before:u,after:e.title?" ":")",...a.current()}))),s(),e.title&&(s=n.enter(`title${o}`),u+=a.move(" "+i),u+=a.move(n.safe(e.title,{before:u,after:i,...a.current()})),u+=a.move(i),s()),u+=a.move(")"),l(),u}function mh(e,t,n){return zl(e,n)?"<":"["}Bl.peek=bh;function Bl(e,t,n,r){const i=e.referenceType,o=n.enter("linkReference");let a=n.enter("label");const l=n.createTracker(r);let s=l.move("[");const u=n.containerPhrasing(e,{before:s,after:"]",...l.current()});s+=l.move(u+"]["),a();const p=n.stack;n.stack=[],a=n.enter("reference");const c=n.safe(n.associationId(e),{before:s,after:"]",...l.current()});return a(),n.stack=p,o(),i==="full"||!u||u!==c?s+=l.move(c+"]"):i==="shortcut"?s=s.slice(0,-1):s+=l.move("]"),s}function bh(){return"["}function zi(e){const t=e.options.bullet||"*";if(t!=="*"&&t!=="+"&&t!=="-")throw new Error("Cannot serialize items with `"+t+"` for `options.bullet`, expected `*`, `+`, or `-`");return t}function yh(e){const t=zi(e),n=e.options.bulletOther;if(!n)return t==="*"?"-":"*";if(n!=="*"&&n!=="+"&&n!=="-")throw new Error("Cannot serialize items with `"+n+"` for `options.bulletOther`, expected `*`, `+`, or `-`");if(n===t)throw new Error("Expected `bullet` (`"+t+"`) and `bulletOther` (`"+n+"`) to be different");return n}function xh(e){const t=e.options.bulletOrdered||".";if(t!=="."&&t!==")")throw new Error("Cannot serialize items with `"+t+"` for `options.bulletOrdered`, expected `.` or `)`");return t}function $l(e){const t=e.options.rule||"*";if(t!=="*"&&t!=="-"&&t!=="_")throw new Error("Cannot serialize rules with `"+t+"` for `options.rule`, expected `*`, `-`, or `_`");return t}function kh(e,t,n,r){const i=n.enter("list"),o=n.bulletCurrent;let a=e.ordered?xh(n):zi(n);const l=e.ordered?a==="."?")":".":yh(n);let s=t&&n.bulletLastUsed?a===n.bulletLastUsed:!1;if(!e.ordered){const p=e.children?e.children[0]:void 0;if((a==="*"||a==="-")&&p&&(!p.children||!p.children[0])&&n.stack[n.stack.length-1]==="list"&&n.stack[n.stack.length-2]==="listItem"&&n.stack[n.stack.length-3]==="list"&&n.stack[n.stack.length-4]==="listItem"&&n.indexStack[n.indexStack.length-1]===0&&n.indexStack[n.indexStack.length-2]===0&&n.indexStack[n.indexStack.length-3]===0&&(s=!0),$l(n)===a&&p){let c=-1;for(;++c-1?t.start:1)+(n.options.incrementListMarker===!1?0:t.children.indexOf(e))+o);let a=o.length+1;(i==="tab"||i==="mixed"&&(t&&t.type==="list"&&t.spread||e.spread))&&(a=Math.ceil(a/4)*4);const l=n.createTracker(r);l.move(o+" ".repeat(a-o.length)),l.shift(a);const s=n.enter("listItem"),u=n.indentLines(n.containerFlow(e,l.current()),p);return s(),u;function p(c,f,d){return f?(d?"":" ".repeat(a))+c:(d?o:o+" ".repeat(a-o.length))+c}}function Sh(e,t,n,r){const i=n.enter("paragraph"),o=n.enter("phrasing"),a=n.containerPhrasing(e,r);return o(),i(),a}const _h=An(["break","delete","emphasis","footnote","footnoteReference","image","imageReference","inlineCode","inlineMath","link","linkReference","mdxJsxTextElement","mdxTextExpression","strong","text","textDirective"]);function Eh(e,t,n,r){return(e.children.some(function(a){return _h(a)})?n.containerPhrasing:n.containerFlow).call(n,e,r)}function Ch(e){const t=e.options.strong||"*";if(t!=="*"&&t!=="_")throw new Error("Cannot serialize strong with `"+t+"` for `options.strong`, expected `*`, or `_`");return t}ql.peek=Th;function ql(e,t,n,r){const i=Ch(n),o=n.enter("strong"),a=n.createTracker(r),l=a.move(i+i);let s=a.move(n.containerPhrasing(e,{after:i,before:l,...a.current()}));const u=s.charCodeAt(0),p=kn(r.before.charCodeAt(r.before.length-1),u,i);p.inside&&(s=Zt(u)+s.slice(1));const c=s.charCodeAt(s.length-1),f=kn(r.after.charCodeAt(0),c,i);f.inside&&(s=s.slice(0,-1)+Zt(c));const d=a.move(i+i);return o(),n.attentionEncodeSurroundingInfo={after:f.outside,before:p.outside},l+s+d}function Th(e,t,n){return n.options.strong||"*"}function Ah(e,t,n,r){return n.safe(e.value,r)}function Lh(e){const t=e.options.ruleRepetition||3;if(t<3)throw new Error("Cannot serialize rules with repetition `"+t+"` for `options.ruleRepetition`, expected `3` or more");return t}function Nh(e,t,n){const r=($l(n)+(n.options.ruleSpaces?" ":"")).repeat(Lh(n));return n.options.ruleSpaces?r.slice(0,-1):r}const Ul={blockquote:Jf,break:Ra,code:ah,definition:lh,emphasis:Rl,hardBreak:Ra,heading:ph,html:Ol,image:Dl,imageReference:Ml,inlineCode:Fl,link:Pl,linkReference:Bl,list:kh,listItem:wh,paragraph:Sh,root:Eh,strong:ql,text:Ah,thematicBreak:Nh};function Ih(){return{enter:{table:jh,tableData:Oa,tableHeader:Oa,tableRow:Oh},exit:{codeText:Dh,table:Rh,tableData:Qn,tableHeader:Qn,tableRow:Qn}}}function jh(e){const t=e._align;this.enter({type:"table",align:t.map(function(n){return n==="none"?null:n}),children:[]},e),this.data.inTable=!0}function Rh(e){this.exit(e),this.data.inTable=void 0}function Oh(e){this.enter({type:"tableRow",children:[]},e)}function Qn(e){this.exit(e)}function Oa(e){this.enter({type:"tableCell",children:[]},e)}function Dh(e){let t=this.resume();this.data.inTable&&(t=t.replace(/\\([\\|])/g,Mh));const n=this.stack[this.stack.length-1];n.type,n.value=t,this.exit(e)}function Mh(e,t){return t==="|"?t:e}function Fh(e){const t=e||{},n=t.tableCellPadding,r=t.tablePipeAlign,i=t.stringLength,o=n?" ":"|";return{unsafe:[{character:"\r",inConstruct:"tableCell"},{character:`
`,inConstruct:"tableCell"},{atBreak:!0,character:"|",after:"[ :-]"},{character:"|",inConstruct:"tableCell"},{atBreak:!0,character:":",after:"-"},{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{inlineCode:f,table:a,tableCell:s,tableRow:l}};function a(d,g,k,S){return u(p(d,k,S),d.align)}function l(d,g,k,S){const x=c(d,k,S),v=u([x]);return v.slice(0,v.indexOf(`
-`))}function s(d,g,k,S){const x=k.enter("tableCell"),v=k.enter("phrasing"),y=k.containerPhrasing(d,{...S,before:o,after:o});return v(),x(),y}function u(d,g){return Yf(d,{align:g,alignDelimiters:r,padding:n,stringLength:i})}function p(d,g,k){const S=d.children;let x=-1;const v=[],y=g.enter("table");for(;++x0&&!n&&(e[e.length-1][1]._gfmAutolinkLiteralWalkedInto=!0),n}const tg={tokenize:ug,partial:!0};function ng(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:og,continuation:{tokenize:lg},exit:sg}},text:{91:{name:"gfmFootnoteCall",tokenize:ag},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:rg,resolveTo:ig}}}}function rg(e,t,n){const r=this;let i=r.events.length;const o=r.parser.gfmFootnotes||(r.parser.gfmFootnotes=[]);let a;for(;i--;){const s=r.events[i][1];if(s.type==="labelImage"){a=s;break}if(s.type==="gfmFootnoteCall"||s.type==="labelLink"||s.type==="label"||s.type==="image"||s.type==="link")break}return l;function l(s){if(!a||!a._balanced)return n(s);const u=Ke(r.sliceSerialize({start:a.end,end:r.now()}));return u.codePointAt(0)!==94||!o.includes(u.slice(1))?n(s):(e.enter("gfmFootnoteCallLabelMarker"),e.consume(s),e.exit("gfmFootnoteCallLabelMarker"),t(s))}}function ig(e,t){let n=e.length;for(;n--;)if(e[n][1].type==="labelImage"&&e[n][0]==="enter"){e[n][1];break}e[n+1][1].type="data",e[n+3][1].type="gfmFootnoteCallLabelMarker";const r={type:"gfmFootnoteCall",start:Object.assign({},e[n+3][1].start),end:Object.assign({},e[e.length-1][1].end)},i={type:"gfmFootnoteCallMarker",start:Object.assign({},e[n+3][1].end),end:Object.assign({},e[n+3][1].end)};i.end.column++,i.end.offset++,i.end._bufferIndex++;const o={type:"gfmFootnoteCallString",start:Object.assign({},i.end),end:Object.assign({},e[e.length-1][1].start)},a={type:"chunkString",contentType:"string",start:Object.assign({},o.start),end:Object.assign({},o.end)},l=[e[n+1],e[n+2],["enter",r,t],e[n+3],e[n+4],["enter",i,t],["exit",i,t],["enter",o,t],["enter",a,t],["exit",a,t],["exit",o,t],e[e.length-2],e[e.length-1],["exit",r,t]];return e.splice(n,e.length-n+1,...l),e}function ag(e,t,n){const r=this,i=r.parser.gfmFootnotes||(r.parser.gfmFootnotes=[]);let o=0,a;return l;function l(c){return e.enter("gfmFootnoteCall"),e.enter("gfmFootnoteCallLabelMarker"),e.consume(c),e.exit("gfmFootnoteCallLabelMarker"),s}function s(c){return c!==94?n(c):(e.enter("gfmFootnoteCallMarker"),e.consume(c),e.exit("gfmFootnoteCallMarker"),e.enter("gfmFootnoteCallString"),e.enter("chunkString").contentType="string",u)}function u(c){if(o>999||c===93&&!a||c===null||c===91||he(c))return n(c);if(c===93){e.exit("chunkString");const f=e.exit("gfmFootnoteCallString");return i.includes(Ke(r.sliceSerialize(f)))?(e.enter("gfmFootnoteCallLabelMarker"),e.consume(c),e.exit("gfmFootnoteCallLabelMarker"),e.exit("gfmFootnoteCall"),t):n(c)}return he(c)||(a=!0),o++,e.consume(c),c===92?p:u}function p(c){return c===91||c===92||c===93?(e.consume(c),o++,u):u(c)}}function og(e,t,n){const r=this,i=r.parser.gfmFootnotes||(r.parser.gfmFootnotes=[]);let o,a=0,l;return s;function s(g){return e.enter("gfmFootnoteDefinition")._container=!0,e.enter("gfmFootnoteDefinitionLabel"),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(g),e.exit("gfmFootnoteDefinitionLabelMarker"),u}function u(g){return g===94?(e.enter("gfmFootnoteDefinitionMarker"),e.consume(g),e.exit("gfmFootnoteDefinitionMarker"),e.enter("gfmFootnoteDefinitionLabelString"),e.enter("chunkString").contentType="string",p):n(g)}function p(g){if(a>999||g===93&&!l||g===null||g===91||he(g))return n(g);if(g===93){e.exit("chunkString");const k=e.exit("gfmFootnoteDefinitionLabelString");return o=Ke(r.sliceSerialize(k)),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(g),e.exit("gfmFootnoteDefinitionLabelMarker"),e.exit("gfmFootnoteDefinitionLabel"),f}return he(g)||(l=!0),a++,e.consume(g),g===92?c:p}function c(g){return g===91||g===92||g===93?(e.consume(g),a++,p):p(g)}function f(g){return g===58?(e.enter("definitionMarker"),e.consume(g),e.exit("definitionMarker"),i.includes(o)||i.push(o),oe(e,d,"gfmFootnoteDefinitionWhitespace")):n(g)}function d(g){return t(g)}}function lg(e,t,n){return e.check(Qt,t,e.attempt(tg,t,n))}function sg(e){e.exit("gfmFootnoteDefinition")}function ug(e,t,n){const r=this;return oe(e,i,"gfmFootnoteDefinitionIndent",5);function i(o){const a=r.events[r.events.length-1];return a&&a[1].type==="gfmFootnoteDefinitionIndent"&&a[2].sliceSerialize(a[1],!0).length===4?t(o):n(o)}}function cg(e){let n=(e||{}).singleTilde;const r={name:"strikethrough",tokenize:o,resolveAll:i};return n==null&&(n=!0),{text:{126:r},insideSpan:{null:[r]},attentionMarkers:{null:[126]}};function i(a,l){let s=-1;for(;++s1?s(g):(a.consume(g),c++,d);if(c<2&&!n)return s(g);const S=a.exit("strikethroughSequenceTemporary"),x=jt(g);return S._open=!x||x===2&&!!k,S._close=!k||k===2&&!!x,l(g)}}}class pg{constructor(){this.map=[]}add(t,n,r){dg(this,t,n,r)}consume(t){if(this.map.sort(function(o,a){return o[0]-a[0]}),this.map.length===0)return;let n=this.map.length;const r=[];for(;n>0;)n-=1,r.push(t.slice(this.map[n][0]+this.map[n][1]),this.map[n][2]),t.length=this.map[n][0];r.push(t.slice()),t.length=0;let i=r.pop();for(;i;){for(const o of i)t.push(o);i=r.pop()}this.map.length=0}}function dg(e,t,n,r){let i=0;if(!(n===0&&r.length===0)){for(;i-1;){const P=r.events[R][1].type;if(P==="lineEnding"||P==="linePrefix")R--;else break}const M=R>-1?r.events[R][1].type:null,H=M==="tableHead"||M==="tableRow"?m:s;return H===m&&r.parser.lazy[r.now().line]?n(E):H(E)}function s(E){return e.enter("tableHead"),e.enter("tableRow"),u(E)}function u(E){return E===124||(a=!0,o+=1),p(E)}function p(E){return E===null?n(E):W(E)?o>1?(o=0,r.interrupt=!0,e.exit("tableRow"),e.enter("lineEnding"),e.consume(E),e.exit("lineEnding"),d):n(E):ne(E)?oe(e,p,"whitespace")(E):(o+=1,a&&(a=!1,i+=1),E===124?(e.enter("tableCellDivider"),e.consume(E),e.exit("tableCellDivider"),a=!0,p):(e.enter("data"),c(E)))}function c(E){return E===null||E===124||he(E)?(e.exit("data"),p(E)):(e.consume(E),E===92?f:c)}function f(E){return E===92||E===124?(e.consume(E),c):c(E)}function d(E){return r.interrupt=!1,r.parser.lazy[r.now().line]?n(E):(e.enter("tableDelimiterRow"),a=!1,ne(E)?oe(e,g,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(E):g(E))}function g(E){return E===45||E===58?S(E):E===124?(a=!0,e.enter("tableCellDivider"),e.consume(E),e.exit("tableCellDivider"),k):C(E)}function k(E){return ne(E)?oe(e,S,"whitespace")(E):S(E)}function S(E){return E===58?(o+=1,a=!0,e.enter("tableDelimiterMarker"),e.consume(E),e.exit("tableDelimiterMarker"),x):E===45?(o+=1,x(E)):E===null||W(E)?_(E):C(E)}function x(E){return E===45?(e.enter("tableDelimiterFiller"),v(E)):C(E)}function v(E){return E===45?(e.consume(E),v):E===58?(a=!0,e.exit("tableDelimiterFiller"),e.enter("tableDelimiterMarker"),e.consume(E),e.exit("tableDelimiterMarker"),y):(e.exit("tableDelimiterFiller"),y(E))}function y(E){return ne(E)?oe(e,_,"whitespace")(E):_(E)}function _(E){return E===124?g(E):E===null||W(E)?!a||i!==o?C(E):(e.exit("tableDelimiterRow"),e.exit("tableHead"),t(E)):C(E)}function C(E){return n(E)}function m(E){return e.enter("tableRow"),T(E)}function T(E){return E===124?(e.enter("tableCellDivider"),e.consume(E),e.exit("tableCellDivider"),T):E===null||W(E)?(e.exit("tableRow"),t(E)):ne(E)?oe(e,T,"whitespace")(E):(e.enter("data"),j(E))}function j(E){return E===null||E===124||he(E)?(e.exit("data"),T(E)):(e.consume(E),E===92?A:j)}function A(E){return E===92||E===124?(e.consume(E),j):j(E)}}function mg(e,t){let n=-1,r=!0,i=0,o=[0,0,0,0],a=[0,0,0,0],l=!1,s=0,u,p,c;const f=new pg;for(;++nn[2]+1){const g=n[2]+1,k=n[3]-n[2]-1;e.add(g,k,[])}}e.add(n[3]+1,0,[["exit",c,t]])}return i!==void 0&&(o.end=Object.assign({},Tt(t.events,i)),e.add(i,0,[["exit",o,t]]),o=void 0),o}function Ma(e,t,n,r,i){const o=[],a=Tt(t.events,n);i&&(i.end=Object.assign({},a),o.push(["exit",i,t])),r.end=Object.assign({},a),o.push(["exit",r,t]),e.add(n+1,0,o)}function Tt(e,t){const n=e[t],r=n[0]==="enter"?"start":"end";return n[1][r]}const yg={name:"tasklistCheck",tokenize:xg};function bg(){return{text:{91:yg}}}function xg(e,t,n){const r=this;return i;function i(s){return r.previous!==null||!r._gfmTasklistFirstContentOfListItem?n(s):(e.enter("taskListCheck"),e.enter("taskListCheckMarker"),e.consume(s),e.exit("taskListCheckMarker"),o)}function o(s){return he(s)?(e.enter("taskListCheckValueUnchecked"),e.consume(s),e.exit("taskListCheckValueUnchecked"),a):s===88||s===120?(e.enter("taskListCheckValueChecked"),e.consume(s),e.exit("taskListCheckValueChecked"),a):n(s)}function a(s){return s===93?(e.enter("taskListCheckMarker"),e.consume(s),e.exit("taskListCheckMarker"),e.exit("taskListCheck"),l):n(s)}function l(s){return W(s)?t(s):ne(s)?e.check({tokenize:kg},t,n)(s):n(s)}}function kg(e,t,n){return oe(e,r,"whitespace");function r(i){return i===null?n(i):t(i)}}function vg(e){return ul([Vh(),ng(),cg(e),hg(),bg()])}const wg={};function Sg(e){const t=this,n=e||wg,r=t.data(),i=r.micromarkExtensions||(r.micromarkExtensions=[]),o=r.fromMarkdownExtensions||(r.fromMarkdownExtensions=[]),a=r.toMarkdownExtensions||(r.toMarkdownExtensions=[]);i.push(vg(n)),o.push(qh()),a.push(Uh(n))}function _g(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function Eg(e,t){if(e==null)return{};var n,r,i=_g(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;re.length)&&(t=e.length);for(var n=0,r=Array(t);n=4)return[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]}var Jn={};function Rg(e){if(e.length===0||e.length===1)return e;var t=e.join(".");return Jn[t]||(Jn[t]=jg(e)),Jn[t]}function Og(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0,r=e.filter(function(o){return o!=="token"}),i=Rg(r);return i.reduce(function(o,a){return At(At({},o),n[a])},t)}function za(e){return e.join(" ")}function Dg(e,t){var n=0;return function(r){return n+=1,r.map(function(i,o){return Jl({node:i,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(o)})})}}function Jl(e){var t=e.node,n=e.stylesheet,r=e.style,i=r===void 0?{}:r,o=e.useInlineStyles,a=e.key,l=t.properties,s=t.type,u=t.tagName,p=t.value;if(s==="text")return p;if(u){var c=Dg(n,o),f;if(!o)f=At(At({},l),{},{className:za(l.className)});else{var d=Object.keys(n).reduce(function(x,v){return v.split(".").forEach(function(y){x.includes(y)||x.push(y)}),x},[]),g=l.className&&l.className.includes("token")?["token"]:[],k=l.className&&g.concat(l.className.filter(function(x){return!d.includes(x)}));f=At(At({},l),{},{className:za(k)||void 0,style:Og(l.className,Object.assign({},l.style,i),n)})}var S=c(t.children);return it.createElement(u,mi({key:a},f),S)}}const Mg=(function(e,t){var n=e.listLanguages();return n.indexOf(t)!==-1});var Fg=["language","children","style","customStyle","codeTagProps","useInlineStyles","showLineNumbers","showInlineLineNumbers","startingLineNumber","lineNumberContainerStyle","lineNumberStyle","wrapLines","wrapLongLines","lineProps","renderer","PreTag","CodeTag","code","astGenerator"];function Pa(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),n.push.apply(n,r)}return n}function ct(e){for(var t=1;t0&&!n&&(e[e.length-1][1]._gfmAutolinkLiteralWalkedInto=!0),n}const tg={tokenize:ug,partial:!0};function ng(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:og,continuation:{tokenize:lg},exit:sg}},text:{91:{name:"gfmFootnoteCall",tokenize:ag},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:rg,resolveTo:ig}}}}function rg(e,t,n){const r=this;let i=r.events.length;const o=r.parser.gfmFootnotes||(r.parser.gfmFootnotes=[]);let a;for(;i--;){const s=r.events[i][1];if(s.type==="labelImage"){a=s;break}if(s.type==="gfmFootnoteCall"||s.type==="labelLink"||s.type==="label"||s.type==="image"||s.type==="link")break}return l;function l(s){if(!a||!a._balanced)return n(s);const u=Ke(r.sliceSerialize({start:a.end,end:r.now()}));return u.codePointAt(0)!==94||!o.includes(u.slice(1))?n(s):(e.enter("gfmFootnoteCallLabelMarker"),e.consume(s),e.exit("gfmFootnoteCallLabelMarker"),t(s))}}function ig(e,t){let n=e.length;for(;n--;)if(e[n][1].type==="labelImage"&&e[n][0]==="enter"){e[n][1];break}e[n+1][1].type="data",e[n+3][1].type="gfmFootnoteCallLabelMarker";const r={type:"gfmFootnoteCall",start:Object.assign({},e[n+3][1].start),end:Object.assign({},e[e.length-1][1].end)},i={type:"gfmFootnoteCallMarker",start:Object.assign({},e[n+3][1].end),end:Object.assign({},e[n+3][1].end)};i.end.column++,i.end.offset++,i.end._bufferIndex++;const o={type:"gfmFootnoteCallString",start:Object.assign({},i.end),end:Object.assign({},e[e.length-1][1].start)},a={type:"chunkString",contentType:"string",start:Object.assign({},o.start),end:Object.assign({},o.end)},l=[e[n+1],e[n+2],["enter",r,t],e[n+3],e[n+4],["enter",i,t],["exit",i,t],["enter",o,t],["enter",a,t],["exit",a,t],["exit",o,t],e[e.length-2],e[e.length-1],["exit",r,t]];return e.splice(n,e.length-n+1,...l),e}function ag(e,t,n){const r=this,i=r.parser.gfmFootnotes||(r.parser.gfmFootnotes=[]);let o=0,a;return l;function l(c){return e.enter("gfmFootnoteCall"),e.enter("gfmFootnoteCallLabelMarker"),e.consume(c),e.exit("gfmFootnoteCallLabelMarker"),s}function s(c){return c!==94?n(c):(e.enter("gfmFootnoteCallMarker"),e.consume(c),e.exit("gfmFootnoteCallMarker"),e.enter("gfmFootnoteCallString"),e.enter("chunkString").contentType="string",u)}function u(c){if(o>999||c===93&&!a||c===null||c===91||he(c))return n(c);if(c===93){e.exit("chunkString");const f=e.exit("gfmFootnoteCallString");return i.includes(Ke(r.sliceSerialize(f)))?(e.enter("gfmFootnoteCallLabelMarker"),e.consume(c),e.exit("gfmFootnoteCallLabelMarker"),e.exit("gfmFootnoteCall"),t):n(c)}return he(c)||(a=!0),o++,e.consume(c),c===92?p:u}function p(c){return c===91||c===92||c===93?(e.consume(c),o++,u):u(c)}}function og(e,t,n){const r=this,i=r.parser.gfmFootnotes||(r.parser.gfmFootnotes=[]);let o,a=0,l;return s;function s(g){return e.enter("gfmFootnoteDefinition")._container=!0,e.enter("gfmFootnoteDefinitionLabel"),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(g),e.exit("gfmFootnoteDefinitionLabelMarker"),u}function u(g){return g===94?(e.enter("gfmFootnoteDefinitionMarker"),e.consume(g),e.exit("gfmFootnoteDefinitionMarker"),e.enter("gfmFootnoteDefinitionLabelString"),e.enter("chunkString").contentType="string",p):n(g)}function p(g){if(a>999||g===93&&!l||g===null||g===91||he(g))return n(g);if(g===93){e.exit("chunkString");const k=e.exit("gfmFootnoteDefinitionLabelString");return o=Ke(r.sliceSerialize(k)),e.enter("gfmFootnoteDefinitionLabelMarker"),e.consume(g),e.exit("gfmFootnoteDefinitionLabelMarker"),e.exit("gfmFootnoteDefinitionLabel"),f}return he(g)||(l=!0),a++,e.consume(g),g===92?c:p}function c(g){return g===91||g===92||g===93?(e.consume(g),a++,p):p(g)}function f(g){return g===58?(e.enter("definitionMarker"),e.consume(g),e.exit("definitionMarker"),i.includes(o)||i.push(o),oe(e,d,"gfmFootnoteDefinitionWhitespace")):n(g)}function d(g){return t(g)}}function lg(e,t,n){return e.check(Qt,t,e.attempt(tg,t,n))}function sg(e){e.exit("gfmFootnoteDefinition")}function ug(e,t,n){const r=this;return oe(e,i,"gfmFootnoteDefinitionIndent",5);function i(o){const a=r.events[r.events.length-1];return a&&a[1].type==="gfmFootnoteDefinitionIndent"&&a[2].sliceSerialize(a[1],!0).length===4?t(o):n(o)}}function cg(e){let n=(e||{}).singleTilde;const r={name:"strikethrough",tokenize:o,resolveAll:i};return n==null&&(n=!0),{text:{126:r},insideSpan:{null:[r]},attentionMarkers:{null:[126]}};function i(a,l){let s=-1;for(;++s1?s(g):(a.consume(g),c++,d);if(c<2&&!n)return s(g);const S=a.exit("strikethroughSequenceTemporary"),x=jt(g);return S._open=!x||x===2&&!!k,S._close=!k||k===2&&!!x,l(g)}}}class pg{constructor(){this.map=[]}add(t,n,r){dg(this,t,n,r)}consume(t){if(this.map.sort(function(o,a){return o[0]-a[0]}),this.map.length===0)return;let n=this.map.length;const r=[];for(;n>0;)n-=1,r.push(t.slice(this.map[n][0]+this.map[n][1]),this.map[n][2]),t.length=this.map[n][0];r.push(t.slice()),t.length=0;let i=r.pop();for(;i;){for(const o of i)t.push(o);i=r.pop()}this.map.length=0}}function dg(e,t,n,r){let i=0;if(!(n===0&&r.length===0)){for(;i-1;){const P=r.events[R][1].type;if(P==="lineEnding"||P==="linePrefix")R--;else break}const M=R>-1?r.events[R][1].type:null,H=M==="tableHead"||M==="tableRow"?m:s;return H===m&&r.parser.lazy[r.now().line]?n(E):H(E)}function s(E){return e.enter("tableHead"),e.enter("tableRow"),u(E)}function u(E){return E===124||(a=!0,o+=1),p(E)}function p(E){return E===null?n(E):W(E)?o>1?(o=0,r.interrupt=!0,e.exit("tableRow"),e.enter("lineEnding"),e.consume(E),e.exit("lineEnding"),d):n(E):ne(E)?oe(e,p,"whitespace")(E):(o+=1,a&&(a=!1,i+=1),E===124?(e.enter("tableCellDivider"),e.consume(E),e.exit("tableCellDivider"),a=!0,p):(e.enter("data"),c(E)))}function c(E){return E===null||E===124||he(E)?(e.exit("data"),p(E)):(e.consume(E),E===92?f:c)}function f(E){return E===92||E===124?(e.consume(E),c):c(E)}function d(E){return r.interrupt=!1,r.parser.lazy[r.now().line]?n(E):(e.enter("tableDelimiterRow"),a=!1,ne(E)?oe(e,g,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(E):g(E))}function g(E){return E===45||E===58?S(E):E===124?(a=!0,e.enter("tableCellDivider"),e.consume(E),e.exit("tableCellDivider"),k):C(E)}function k(E){return ne(E)?oe(e,S,"whitespace")(E):S(E)}function S(E){return E===58?(o+=1,a=!0,e.enter("tableDelimiterMarker"),e.consume(E),e.exit("tableDelimiterMarker"),x):E===45?(o+=1,x(E)):E===null||W(E)?_(E):C(E)}function x(E){return E===45?(e.enter("tableDelimiterFiller"),v(E)):C(E)}function v(E){return E===45?(e.consume(E),v):E===58?(a=!0,e.exit("tableDelimiterFiller"),e.enter("tableDelimiterMarker"),e.consume(E),e.exit("tableDelimiterMarker"),b):(e.exit("tableDelimiterFiller"),b(E))}function b(E){return ne(E)?oe(e,_,"whitespace")(E):_(E)}function _(E){return E===124?g(E):E===null||W(E)?!a||i!==o?C(E):(e.exit("tableDelimiterRow"),e.exit("tableHead"),t(E)):C(E)}function C(E){return n(E)}function m(E){return e.enter("tableRow"),T(E)}function T(E){return E===124?(e.enter("tableCellDivider"),e.consume(E),e.exit("tableCellDivider"),T):E===null||W(E)?(e.exit("tableRow"),t(E)):ne(E)?oe(e,T,"whitespace")(E):(e.enter("data"),j(E))}function j(E){return E===null||E===124||he(E)?(e.exit("data"),T(E)):(e.consume(E),E===92?A:j)}function A(E){return E===92||E===124?(e.consume(E),j):j(E)}}function mg(e,t){let n=-1,r=!0,i=0,o=[0,0,0,0],a=[0,0,0,0],l=!1,s=0,u,p,c;const f=new pg;for(;++nn[2]+1){const g=n[2]+1,k=n[3]-n[2]-1;e.add(g,k,[])}}e.add(n[3]+1,0,[["exit",c,t]])}return i!==void 0&&(o.end=Object.assign({},Tt(t.events,i)),e.add(i,0,[["exit",o,t]]),o=void 0),o}function Ma(e,t,n,r,i){const o=[],a=Tt(t.events,n);i&&(i.end=Object.assign({},a),o.push(["exit",i,t])),r.end=Object.assign({},a),o.push(["exit",r,t]),e.add(n+1,0,o)}function Tt(e,t){const n=e[t],r=n[0]==="enter"?"start":"end";return n[1][r]}const bg={name:"tasklistCheck",tokenize:xg};function yg(){return{text:{91:bg}}}function xg(e,t,n){const r=this;return i;function i(s){return r.previous!==null||!r._gfmTasklistFirstContentOfListItem?n(s):(e.enter("taskListCheck"),e.enter("taskListCheckMarker"),e.consume(s),e.exit("taskListCheckMarker"),o)}function o(s){return he(s)?(e.enter("taskListCheckValueUnchecked"),e.consume(s),e.exit("taskListCheckValueUnchecked"),a):s===88||s===120?(e.enter("taskListCheckValueChecked"),e.consume(s),e.exit("taskListCheckValueChecked"),a):n(s)}function a(s){return s===93?(e.enter("taskListCheckMarker"),e.consume(s),e.exit("taskListCheckMarker"),e.exit("taskListCheck"),l):n(s)}function l(s){return W(s)?t(s):ne(s)?e.check({tokenize:kg},t,n)(s):n(s)}}function kg(e,t,n){return oe(e,r,"whitespace");function r(i){return i===null?n(i):t(i)}}function vg(e){return ul([Vh(),ng(),cg(e),hg(),yg()])}const wg={};function Sg(e){const t=this,n=e||wg,r=t.data(),i=r.micromarkExtensions||(r.micromarkExtensions=[]),o=r.fromMarkdownExtensions||(r.fromMarkdownExtensions=[]),a=r.toMarkdownExtensions||(r.toMarkdownExtensions=[]);i.push(vg(n)),o.push(qh()),a.push(Uh(n))}function _g(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function Eg(e,t){if(e==null)return{};var n,r,i=_g(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;re.length)&&(t=e.length);for(var n=0,r=Array(t);n=4)return[e[0],e[1],e[2],e[3],"".concat(e[0],".").concat(e[1]),"".concat(e[0],".").concat(e[2]),"".concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[0]),"".concat(e[1],".").concat(e[2]),"".concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[1]),"".concat(e[2],".").concat(e[3]),"".concat(e[3],".").concat(e[0]),"".concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[0]),"".concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[0],".").concat(e[1],".").concat(e[2],".").concat(e[3]),"".concat(e[0],".").concat(e[1],".").concat(e[3],".").concat(e[2]),"".concat(e[0],".").concat(e[2],".").concat(e[1],".").concat(e[3]),"".concat(e[0],".").concat(e[2],".").concat(e[3],".").concat(e[1]),"".concat(e[0],".").concat(e[3],".").concat(e[1],".").concat(e[2]),"".concat(e[0],".").concat(e[3],".").concat(e[2],".").concat(e[1]),"".concat(e[1],".").concat(e[0],".").concat(e[2],".").concat(e[3]),"".concat(e[1],".").concat(e[0],".").concat(e[3],".").concat(e[2]),"".concat(e[1],".").concat(e[2],".").concat(e[0],".").concat(e[3]),"".concat(e[1],".").concat(e[2],".").concat(e[3],".").concat(e[0]),"".concat(e[1],".").concat(e[3],".").concat(e[0],".").concat(e[2]),"".concat(e[1],".").concat(e[3],".").concat(e[2],".").concat(e[0]),"".concat(e[2],".").concat(e[0],".").concat(e[1],".").concat(e[3]),"".concat(e[2],".").concat(e[0],".").concat(e[3],".").concat(e[1]),"".concat(e[2],".").concat(e[1],".").concat(e[0],".").concat(e[3]),"".concat(e[2],".").concat(e[1],".").concat(e[3],".").concat(e[0]),"".concat(e[2],".").concat(e[3],".").concat(e[0],".").concat(e[1]),"".concat(e[2],".").concat(e[3],".").concat(e[1],".").concat(e[0]),"".concat(e[3],".").concat(e[0],".").concat(e[1],".").concat(e[2]),"".concat(e[3],".").concat(e[0],".").concat(e[2],".").concat(e[1]),"".concat(e[3],".").concat(e[1],".").concat(e[0],".").concat(e[2]),"".concat(e[3],".").concat(e[1],".").concat(e[2],".").concat(e[0]),"".concat(e[3],".").concat(e[2],".").concat(e[0],".").concat(e[1]),"".concat(e[3],".").concat(e[2],".").concat(e[1],".").concat(e[0])]}var Jn={};function Rg(e){if(e.length===0||e.length===1)return e;var t=e.join(".");return Jn[t]||(Jn[t]=jg(e)),Jn[t]}function Og(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0,r=e.filter(function(o){return o!=="token"}),i=Rg(r);return i.reduce(function(o,a){return At(At({},o),n[a])},t)}function za(e){return e.join(" ")}function Dg(e,t){var n=0;return function(r){return n+=1,r.map(function(i,o){return Jl({node:i,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(o)})})}}function Jl(e){var t=e.node,n=e.stylesheet,r=e.style,i=r===void 0?{}:r,o=e.useInlineStyles,a=e.key,l=t.properties,s=t.type,u=t.tagName,p=t.value;if(s==="text")return p;if(u){var c=Dg(n,o),f;if(!o)f=At(At({},l),{},{className:za(l.className)});else{var d=Object.keys(n).reduce(function(x,v){return v.split(".").forEach(function(b){x.includes(b)||x.push(b)}),x},[]),g=l.className&&l.className.includes("token")?["token"]:[],k=l.className&&g.concat(l.className.filter(function(x){return!d.includes(x)}));f=At(At({},l),{},{className:za(k)||void 0,style:Og(l.className,Object.assign({},l.style,i),n)})}var S=c(t.children);return it.createElement(u,mi({key:a},f),S)}}const Mg=(function(e,t){var n=e.listLanguages();return n.indexOf(t)!==-1});var Fg=["language","children","style","customStyle","codeTagProps","useInlineStyles","showLineNumbers","showInlineLineNumbers","startingLineNumber","lineNumberContainerStyle","lineNumberStyle","wrapLines","wrapLongLines","lineProps","renderer","PreTag","CodeTag","code","astGenerator"];function Pa(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable})),n.push.apply(n,r)}return n}function ct(e){for(var t=1;t1&&arguments[1]!==void 0?arguments[1]:[],n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:[],r=0;r2&&arguments[2]!==void 0?arguments[2]:[];return hn({children:C,lineNumber:m,lineNumberStyle:l,largestLineNumber:a,showInlineLineNumbers:i,lineProps:n,className:T,showLineNumbers:r,wrapLongLines:s,wrapLines:t})}function k(C,m){if(r&&m&&i){var T=ts(l,m,a);C.unshift(es(m,T))}return C}function S(C,m){var T=arguments.length>2&&arguments[2]!==void 0?arguments[2]:[];return t||T.length>0?g(C,m,T):k(C,m)}for(var x=function(){var m=p[d],T=m.children[0].value,j=Pg(T);if(j){var A=T.split(`
`);A.forEach(function(E,R){var M=r&&c.length+o,H={type:"text",value:"".concat(E,`
-`)};if(R===0){var P=p.slice(f+1,d).concat(hn({children:[H],className:m.properties.className})),z=S(P,M);c.push(z)}else if(R===A.length-1){var G=p[d+1]&&p[d+1].children&&p[d+1].children[0],J={type:"text",value:"".concat(E)};if(G){var U=hn({children:[J],className:m.properties.className});p.splice(d+1,0,U)}else{var ie=[J],w=S(ie,M,m.properties.className);c.push(w)}}else{var K=[H],Y=S(K,M,m.properties.className);c.push(Y)}}),f=d}d++};d4&&g.slice(0,4)===r&&i.test(d)&&(d.charAt(4)==="-"?k=s(d):d=u(d),S=t),new S(k,d))}function s(f){var d=f.slice(5).replace(o,c);return r+d.charAt(0).toUpperCase()+d.slice(1)}function u(f){var d=f.slice(4);return o.test(d)?f:(d=d.replace(a,p),d.charAt(0)!=="-"&&(d="-"+d),r+d)}function p(f){return"-"+f.toLowerCase()}function c(f){return f.charAt(1).toUpperCase()}return gr}var mr,ro;function rm(){if(ro)return mr;ro=1,mr=t;var e=/[#.]/g;function t(n,r){for(var i=n||"",o=r||"div",a={},l=0,s,u,p;l",Em="Í",Cm="Î",Tm="Ì",Am="Ï",Lm="<",Nm="Ñ",Im="Ó",jm="Ô",Rm="Ò",Om="Ø",Dm="Õ",Mm="Ö",Fm='"',zm="®",Pm="Þ",Bm="Ú",$m="Û",qm="Ù",Um="Ü",Hm="Ý",Wm="á",Vm="â",Gm="´",Zm="æ",Xm="à",Km="&",Ym="å",Qm="ã",Jm="ä",ey="¦",ty="ç",ny="¸",ry="¢",iy="©",ay="¤",oy="°",ly="÷",sy="é",uy="ê",cy="è",py="ð",dy="ë",fy="½",hy="¼",gy="¾",my=">",yy="í",by="î",xy="¡",ky="ì",vy="¿",wy="ï",Sy="«",_y="<",Ey="¯",Cy="µ",Ty="·",Ay=" ",Ly="¬",Ny="ñ",Iy="ó",jy="ô",Ry="ò",Oy="ª",Dy="º",My="ø",Fy="õ",zy="ö",Py="¶",By="±",$y="£",qy='"',Uy="»",Hy="®",Wy="§",Vy="",Gy="¹",Zy="²",Xy="³",Ky="ß",Yy="þ",Qy="×",Jy="ú",eb="û",tb="ù",nb="¨",rb="ü",ib="ý",ab="¥",ob="ÿ",lb={AElig:um,AMP:cm,Aacute:pm,Acirc:dm,Agrave:fm,Aring:hm,Atilde:gm,Auml:mm,COPY:ym,Ccedil:bm,ETH:xm,Eacute:km,Ecirc:vm,Egrave:wm,Euml:Sm,GT:_m,Iacute:Em,Icirc:Cm,Igrave:Tm,Iuml:Am,LT:Lm,Ntilde:Nm,Oacute:Im,Ocirc:jm,Ograve:Rm,Oslash:Om,Otilde:Dm,Ouml:Mm,QUOT:Fm,REG:zm,THORN:Pm,Uacute:Bm,Ucirc:$m,Ugrave:qm,Uuml:Um,Yacute:Hm,aacute:Wm,acirc:Vm,acute:Gm,aelig:Zm,agrave:Xm,amp:Km,aring:Ym,atilde:Qm,auml:Jm,brvbar:ey,ccedil:ty,cedil:ny,cent:ry,copy:iy,curren:ay,deg:oy,divide:ly,eacute:sy,ecirc:uy,egrave:cy,eth:py,euml:dy,frac12:fy,frac14:hy,frac34:gy,gt:my,iacute:yy,icirc:by,iexcl:xy,igrave:ky,iquest:vy,iuml:wy,laquo:Sy,lt:_y,macr:Ey,micro:Cy,middot:Ty,nbsp:Ay,not:Ly,ntilde:Ny,oacute:Iy,ocirc:jy,ograve:Ry,ordf:Oy,ordm:Dy,oslash:My,otilde:Fy,ouml:zy,para:Py,plusmn:By,pound:$y,quot:qy,raquo:Uy,reg:Hy,sect:Wy,shy:Vy,sup1:Gy,sup2:Zy,sup3:Xy,szlig:Ky,thorn:Yy,times:Qy,uacute:Jy,ucirc:eb,ugrave:tb,uml:nb,uuml:rb,yacute:ib,yen:ab,yuml:ob},sb={0:"�",128:"€",130:"‚",131:"ƒ",132:"„",133:"…",134:"†",135:"‡",136:"ˆ",137:"‰",138:"Š",139:"‹",140:"Œ",142:"Ž",145:"‘",146:"’",147:"“",148:"”",149:"•",150:"–",151:"—",152:"˜",153:"™",154:"š",155:"›",156:"œ",158:"ž",159:"Ÿ"};var kr,uo;function ss(){if(uo)return kr;uo=1,kr=e;function e(t){var n=typeof t=="string"?t.charCodeAt(0):t;return n>=48&&n<=57}return kr}var vr,co;function ub(){if(co)return vr;co=1,vr=e;function e(t){var n=typeof t=="string"?t.charCodeAt(0):t;return n>=97&&n<=102||n>=65&&n<=70||n>=48&&n<=57}return vr}var wr,po;function cb(){if(po)return wr;po=1,wr=e;function e(t){var n=typeof t=="string"?t.charCodeAt(0):t;return n>=97&&n<=122||n>=65&&n<=90}return wr}var Sr,fo;function pb(){if(fo)return Sr;fo=1;var e=cb(),t=ss();Sr=n;function n(r){return e(r)||t(r)}return Sr}var _r,ho;function db(){if(ho)return _r;ho=1;var e,t=59;_r=n;function n(r){var i="&"+r+";",o;return e=e||document.createElement("i"),e.innerHTML=i,o=e.textContent,o.charCodeAt(o.length-1)===t&&r!=="semi"||o===i?!1:o}return _r}var Er,go;function fb(){if(go)return Er;go=1;var e=lb,t=sb,n=ss(),r=ub(),i=pb(),o=db();Er=ie;var a={}.hasOwnProperty,l=String.fromCharCode,s=Function.prototype,u={warning:null,reference:null,text:null,warningContext:null,referenceContext:null,textContext:null,position:{},additional:null,attribute:!1,nonTerminated:!0},p=9,c=10,f=12,d=32,g=38,k=59,S=60,x=61,v=35,y=88,_=120,C=65533,m="named",T="hexadecimal",j="decimal",A={};A[T]=16,A[j]=10;var E={};E[m]=i,E[j]=n,E[T]=r;var R=1,M=2,H=3,P=4,z=5,G=6,J=7,U={};U[R]="Named character references must be terminated by a semicolon",U[M]="Numeric character references must be terminated by a semicolon",U[H]="Named character references cannot be empty",U[P]="Numeric character references cannot be empty",U[z]="Named character references must be known",U[G]="Numeric character references cannot be disallowed",U[J]="Numeric character references cannot be outside the permissible Unicode range";function ie(b,Z){var ee={},te,xe;Z||(Z={});for(xe in u)te=Z[xe],ee[xe]=te??u[xe];return(ee.position.indent||ee.position.start)&&(ee.indent=ee.position.indent||[],ee.position=ee.position.start),w(b,ee)}function w(b,Z){var ee=Z.additional,te=Z.nonTerminated,xe=Z.text,we=Z.reference,_e=Z.warning,Ce=Z.textContext,ye=Z.referenceContext,qe=Z.warningContext,le=Z.position,ce=Z.indent||[],Ze=b.length,Ae=0,Xe=-1,Me=le.column||1,dt=le.line||1,Fe="",Qe=[],Ue,ft,He,se,L,D,B,V,re,ke,Te,ve,je,pe,Se,ze,Le,Ne,be;for(typeof ee=="string"&&(ee=ee.charCodeAt(0)),ze=lt(),V=_e?Nn:s,Ae--,Ze++;++Ae65535&&(D-=65536,ke+=l(D>>>10|55296),D=56320|D&1023),D=ke+l(D))):pe!==m&&V(P,Ne)),D?(tn(),ze=lt(),Ae=be-1,Me+=be-je+1,Qe.push(D),Le=lt(),Le.offset++,we&&we.call(ye,D,{start:ze,end:Le},b.slice(je-1,be)),ze=Le):(se=b.slice(je-1,be),Fe+=se,Me+=se.length,Ae=be-1)}else L===10&&(dt++,Xe++,Me=0),L===L?(Fe+=l(L),Me++):tn();return Qe.join("");function lt(){return{line:dt,column:Me,offset:Ae+(le.offset||0)}}function Nn(ht,gt){var mt=lt();mt.column+=gt,mt.offset+=gt,_e.call(qe,U[ht],mt,ht)}function tn(){Fe&&(Qe.push(Fe),xe&&xe.call(Ce,Fe,{start:ze,end:lt()}),Fe="")}}function K(b){return b>=55296&&b<=57343||b>1114111}function Y(b){return b>=1&&b<=8||b===11||b>=13&&b<=31||b>=127&&b<=159||b>=64976&&b<=65007||(b&65535)===65535||(b&65535)===65534}return Er}var Cr={exports:{}},mo;function hb(){return mo||(mo=1,(function(e){var t=typeof window<"u"?window:typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?self:{};var n=(function(r){var i=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,o=0,a={},l={manual:r.Prism&&r.Prism.manual,disableWorkerMessageHandler:r.Prism&&r.Prism.disableWorkerMessageHandler,util:{encode:function v(y){return y instanceof s?new s(y.type,v(y.content),y.alias):Array.isArray(y)?y.map(v):y.replace(/&/g,"&").replace(/"u")return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(C){var v=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(C.stack)||[])[1];if(v){var y=document.getElementsByTagName("script");for(var _ in y)if(y[_].src==v)return y[_]}return null}},isActive:function(v,y,_){for(var C="no-"+y;v;){var m=v.classList;if(m.contains(y))return!0;if(m.contains(C))return!1;v=v.parentElement}return!!_}},languages:{plain:a,plaintext:a,text:a,txt:a,extend:function(v,y){var _=l.util.clone(l.languages[v]);for(var C in y)_[C]=y[C];return _},insertBefore:function(v,y,_,C){C=C||l.languages;var m=C[v],T={};for(var j in m)if(m.hasOwnProperty(j)){if(j==y)for(var A in _)_.hasOwnProperty(A)&&(T[A]=_[A]);_.hasOwnProperty(j)||(T[j]=m[j])}var E=C[v];return C[v]=T,l.languages.DFS(l.languages,function(R,M){M===E&&R!=v&&(this[R]=T)}),T},DFS:function v(y,_,C,m){m=m||{};var T=l.util.objId;for(var j in y)if(y.hasOwnProperty(j)){_.call(y,j,y[j],C||j);var A=y[j],E=l.util.type(A);E==="Object"&&!m[T(A)]?(m[T(A)]=!0,v(A,_,null,m)):E==="Array"&&!m[T(A)]&&(m[T(A)]=!0,v(A,_,j,m))}}},plugins:{},highlightAll:function(v,y){l.highlightAllUnder(document,v,y)},highlightAllUnder:function(v,y,_){var C={callback:_,container:v,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};l.hooks.run("before-highlightall",C),C.elements=Array.prototype.slice.apply(C.container.querySelectorAll(C.selector)),l.hooks.run("before-all-elements-highlight",C);for(var m=0,T;T=C.elements[m++];)l.highlightElement(T,y===!0,C.callback)},highlightElement:function(v,y,_){var C=l.util.getLanguage(v),m=l.languages[C];l.util.setLanguage(v,C);var T=v.parentElement;T&&T.nodeName.toLowerCase()==="pre"&&l.util.setLanguage(T,C);var j=v.textContent,A={element:v,language:C,grammar:m,code:j};function E(M){A.highlightedCode=M,l.hooks.run("before-insert",A),A.element.innerHTML=A.highlightedCode,l.hooks.run("after-highlight",A),l.hooks.run("complete",A),_&&_.call(A.element)}if(l.hooks.run("before-sanity-check",A),T=A.element.parentElement,T&&T.nodeName.toLowerCase()==="pre"&&!T.hasAttribute("tabindex")&&T.setAttribute("tabindex","0"),!A.code){l.hooks.run("complete",A),_&&_.call(A.element);return}if(l.hooks.run("before-highlight",A),!A.grammar){E(l.util.encode(A.code));return}if(y&&r.Worker){var R=new Worker(l.filename);R.onmessage=function(M){E(M.data)},R.postMessage(JSON.stringify({language:A.language,code:A.code,immediateClose:!0}))}else E(l.highlight(A.code,A.grammar,A.language))},highlight:function(v,y,_){var C={code:v,grammar:y,language:_};if(l.hooks.run("before-tokenize",C),!C.grammar)throw new Error('The language "'+C.language+'" has no grammar.');return C.tokens=l.tokenize(C.code,C.grammar),l.hooks.run("after-tokenize",C),s.stringify(l.util.encode(C.tokens),C.language)},tokenize:function(v,y){var _=y.rest;if(_){for(var C in _)y[C]=_[C];delete y.rest}var m=new c;return f(m,m.head,v),p(v,m,y,m.head,0),g(m)},hooks:{all:{},add:function(v,y){var _=l.hooks.all;_[v]=_[v]||[],_[v].push(y)},run:function(v,y){var _=l.hooks.all[v];if(!(!_||!_.length))for(var C=0,m;m=_[C++];)m(y)}},Token:s};r.Prism=l;function s(v,y,_,C){this.type=v,this.content=y,this.alias=_,this.length=(C||"").length|0}s.stringify=function v(y,_){if(typeof y=="string")return y;if(Array.isArray(y)){var C="";return y.forEach(function(E){C+=v(E,_)}),C}var m={type:y.type,content:v(y.content,_),tag:"span",classes:["token",y.type],attributes:{},language:_},T=y.alias;T&&(Array.isArray(T)?Array.prototype.push.apply(m.classes,T):m.classes.push(T)),l.hooks.run("wrap",m);var j="";for(var A in m.attributes)j+=" "+A+'="'+(m.attributes[A]||"").replace(/"/g,""")+'"';return"<"+m.tag+' class="'+m.classes.join(" ")+'"'+j+">"+m.content+""+m.tag+">"};function u(v,y,_,C){v.lastIndex=y;var m=v.exec(_);if(m&&C&&m[1]){var T=m[1].length;m.index+=T,m[0]=m[0].slice(T)}return m}function p(v,y,_,C,m,T){for(var j in _)if(!(!_.hasOwnProperty(j)||!_[j])){var A=_[j];A=Array.isArray(A)?A:[A];for(var E=0;E=T.reach);ie+=U.value.length,U=U.next){var w=U.value;if(y.length>v.length)return;if(!(w instanceof s)){var K=1,Y;if(P){if(Y=u(J,ie,v,H),!Y||Y.index>=v.length)break;var te=Y.index,b=Y.index+Y[0].length,Z=ie;for(Z+=U.value.length;te>=Z;)U=U.next,Z+=U.value.length;if(Z-=U.value.length,ie=Z,U.value instanceof s)continue;for(var ee=U;ee!==y.tail&&(ZT.reach&&(T.reach=Ce);var ye=U.prev;we&&(ye=f(y,ye,we),ie+=we.length),d(y,ye,K);var qe=new s(j,M?l.tokenize(xe,M):xe,z,xe);if(U=f(y,ye,qe),_e&&f(y,U,_e),K>1){var le={cause:j+","+E,reach:Ce};p(v,y,_,U.prev,ie,le),T&&le.reach>T.reach&&(T.reach=le.reach)}}}}}}function c(){var v={value:null,prev:null,next:null},y={value:null,prev:v,next:null};v.next=y,this.head=v,this.tail=y,this.length=0}function f(v,y,_){var C=y.next,m={value:_,prev:y,next:C};return y.next=m,C.prev=m,v.length++,m}function d(v,y,_){for(var C=y.next,m=0;m<_&&C!==v.tail;m++)C=C.next;y.next=C,C.prev=y,v.length-=m}function g(v){for(var y=[],_=v.head.next;_!==v.tail;)y.push(_.value),_=_.next;return y}if(!r.document)return r.addEventListener&&(l.disableWorkerMessageHandler||r.addEventListener("message",function(v){var y=JSON.parse(v.data),_=y.language,C=y.code,m=y.immediateClose;r.postMessage(l.highlight(C,l.languages[_],_)),m&&r.close()},!1)),l;var k=l.util.currentScript();k&&(l.filename=k.src,k.hasAttribute("data-manual")&&(l.manual=!0));function S(){l.manual||l.highlightAll()}if(!l.manual){var x=document.readyState;x==="loading"||x==="interactive"&&k&&k.defer?document.addEventListener("DOMContentLoaded",S):window.requestAnimationFrame?window.requestAnimationFrame(S):window.setTimeout(S,16)}return l})(t);e.exports&&(e.exports=n),typeof mn<"u"&&(mn.Prism=n)})(Cr)),Cr.exports}var Tr,yo;function us(){if(yo)return Tr;yo=1,Tr=e,e.displayName="markup",e.aliases=["html","mathml","svg","xml","ssml","atom","rss"];function e(t){t.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/?[\da-f]{1,8};/i]},t.languages.markup.tag.inside["attr-value"].inside.entity=t.languages.markup.entity,t.languages.markup.doctype.inside["internal-subset"].inside=t.languages.markup,t.hooks.add("wrap",function(n){n.type==="entity"&&(n.attributes.title=n.content.value.replace(/&/,"&"))}),Object.defineProperty(t.languages.markup.tag,"addInlined",{value:function(r,i){var o={};o["language-"+i]={pattern:/(^$)/i,lookbehind:!0,inside:t.languages[i]},o.cdata=/^$/i;var a={"included-cdata":{pattern://i,inside:o}};a["language-"+i]={pattern:/[\s\S]+/,inside:t.languages[i]};var l={};l[r]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,function(){return r}),"i"),lookbehind:!0,greedy:!0,inside:a},t.languages.insertBefore("markup","cdata",l)}}),Object.defineProperty(t.languages.markup.tag,"addAttribute",{value:function(n,r){t.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+n+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[r,"language-"+r],inside:t.languages[r]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),t.languages.html=t.languages.markup,t.languages.mathml=t.languages.markup,t.languages.svg=t.languages.markup,t.languages.xml=t.languages.extend("markup",{}),t.languages.ssml=t.languages.xml,t.languages.atom=t.languages.xml,t.languages.rss=t.languages.xml}return Tr}var Ar,bo;function cs(){if(bo)return Ar;bo=1,Ar=e,e.displayName="css",e.aliases=[];function e(t){(function(n){var r=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;n.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+r.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+r.source+"$"),alias:"url"}}},selector:{pattern:RegExp(`(^|[{}\\s])[^{}\\s](?:[^{};"'\\s]|\\s+(?![\\s{])|`+r.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:r,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},n.languages.css.atrule.inside.rest=n.languages.css;var i=n.languages.markup;i&&(i.tag.addInlined("style","css"),i.tag.addAttribute("style","css"))})(t)}return Ar}var Lr,xo;function gb(){if(xo)return Lr;xo=1,Lr=e,e.displayName="clike",e.aliases=[];function e(t){t.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}}return Lr}var Nr,ko;function ps(){if(ko)return Nr;ko=1,Nr=e,e.displayName="javascript",e.aliases=["js"];function e(t){t.languages.javascript=t.languages.extend("clike",{"class-name":[t.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+(/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source)+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),t.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,t.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:t.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:t.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:t.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:t.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:t.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),t.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:t.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),t.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),t.languages.markup&&(t.languages.markup.tag.addInlined("script","javascript"),t.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),t.languages.js=t.languages.javascript}return Nr}var Ir,vo;function mb(){if(vo)return Ir;vo=1;var e=typeof globalThis=="object"?globalThis:typeof self=="object"?self:typeof window=="object"?window:typeof mn=="object"?mn:{},t=C();e.Prism={manual:!0,disableWorkerMessageHandler:!0};var n=sm(),r=fb(),i=hb(),o=us(),a=cs(),l=gb(),s=ps();t();var u={}.hasOwnProperty;function p(){}p.prototype=i;var c=new p;Ir=c,c.highlight=g,c.register=f,c.alias=d,c.registered=k,c.listLanguages=S,f(o),f(a),f(l),f(s),c.util.encode=y,c.Token.stringify=x;function f(m){if(typeof m!="function"||!m.displayName)throw new Error("Expected `function` for `grammar`, got `"+m+"`");c.languages[m.displayName]===void 0&&m(c)}function d(m,T){var j=c.languages,A=m,E,R,M,H;T&&(A={},A[m]=T);for(E in A)for(R=A[E],R=typeof R=="string"?[R]:R,M=R.length,H=-1;++H?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/}}return jr}var Rr,So;function ds(){if(So)return Rr;So=1,Rr=e,e.displayName="c",e.aliases=[];function e(t){t.languages.c=t.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),t.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),t.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},t.languages.c.string],char:t.languages.c.char,comment:t.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:t.languages.c}}}}),t.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete t.languages.c.boolean}return Rr}var Or,_o;function xb(){if(_o)return Or;_o=1;var e=ds();Or=t,t.displayName="cpp",t.aliases=[];function t(n){n.register(e),(function(r){var i=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,o=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,function(){return i.source});r.languages.cpp=r.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,function(){return i.source})),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:i,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),r.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,function(){return o})+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),r.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:r.languages.cpp}}}}),r.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),r.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:r.languages.extend("cpp",{})}}),r.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},r.languages.cpp["base-clause"])})(n)}return Or}var Dr,Eo;function kb(){if(Eo)return Dr;Eo=1,Dr=e,e.displayName="csharp",e.aliases=["dotnet","cs"];function e(t){(function(n){function r(K,Y){return K.replace(/<<(\d+)>>/g,function(b,Z){return"(?:"+Y[+Z]+")"})}function i(K,Y,b){return RegExp(r(K,Y),"")}function o(K,Y){for(var b=0;b>/g,function(){return"(?:"+K+")"});return K.replace(/<>/g,"[^\\s\\S]")}var a={type:"bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",typeDeclaration:"class enum interface record struct",contextual:"add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",other:"abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield"};function l(K){return"\\b(?:"+K.trim().replace(/ /g,"|")+")\\b"}var s=l(a.typeDeclaration),u=RegExp(l(a.type+" "+a.typeDeclaration+" "+a.contextual+" "+a.other)),p=l(a.typeDeclaration+" "+a.contextual+" "+a.other),c=l(a.type+" "+a.typeDeclaration+" "+a.other),f=o(/<(?:[^<>;=+\-*/%&|^]|<>)*>/.source,2),d=o(/\((?:[^()]|<>)*\)/.source,2),g=/@?\b[A-Za-z_]\w*\b/.source,k=r(/<<0>>(?:\s*<<1>>)?/.source,[g,f]),S=r(/(?!<<0>>)<<1>>(?:\s*\.\s*<<1>>)*/.source,[p,k]),x=/\[\s*(?:,\s*)*\]/.source,v=r(/<<0>>(?:\s*(?:\?\s*)?<<1>>)*(?:\s*\?)?/.source,[S,x]),y=r(/[^,()<>[\];=+\-*/%&|^]|<<0>>|<<1>>|<<2>>/.source,[f,d,x]),_=r(/\(<<0>>+(?:,<<0>>+)+\)/.source,[y]),C=r(/(?:<<0>>|<<1>>)(?:\s*(?:\?\s*)?<<2>>)*(?:\s*\?)?/.source,[_,S,x]),m={keyword:u,punctuation:/[<>()?,.:[\]]/},T=/'(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'/.source,j=/"(?:\\.|[^\\"\r\n])*"/.source,A=/@"(?:""|\\[\s\S]|[^\\"])*"(?!")/.source;n.languages.csharp=n.languages.extend("clike",{string:[{pattern:i(/(^|[^$\\])<<0>>/.source,[A]),lookbehind:!0,greedy:!0},{pattern:i(/(^|[^@$\\])<<0>>/.source,[j]),lookbehind:!0,greedy:!0}],"class-name":[{pattern:i(/(\busing\s+static\s+)<<0>>(?=\s*;)/.source,[S]),lookbehind:!0,inside:m},{pattern:i(/(\busing\s+<<0>>\s*=\s*)<<1>>(?=\s*;)/.source,[g,C]),lookbehind:!0,inside:m},{pattern:i(/(\busing\s+)<<0>>(?=\s*=)/.source,[g]),lookbehind:!0},{pattern:i(/(\b<<0>>\s+)<<1>>/.source,[s,k]),lookbehind:!0,inside:m},{pattern:i(/(\bcatch\s*\(\s*)<<0>>/.source,[S]),lookbehind:!0,inside:m},{pattern:i(/(\bwhere\s+)<<0>>/.source,[g]),lookbehind:!0},{pattern:i(/(\b(?:is(?:\s+not)?|as)\s+)<<0>>/.source,[v]),lookbehind:!0,inside:m},{pattern:i(/\b<<0>>(?=\s+(?!<<1>>|with\s*\{)<<2>>(?:\s*[=,;:{)\]]|\s+(?:in|when)\b))/.source,[C,c,g]),inside:m}],keyword:u,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),n.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),n.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:i(/([(,]\s*)<<0>>(?=\s*:)/.source,[g]),lookbehind:!0,alias:"punctuation"}}),n.languages.insertBefore("csharp","class-name",{namespace:{pattern:i(/(\b(?:namespace|using)\s+)<<0>>(?:\s*\.\s*<<0>>)*(?=\s*[;{])/.source,[g]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:i(/(\b(?:default|sizeof|typeof)\s*\(\s*(?!\s))(?:[^()\s]|\s(?!\s)|<<0>>)*(?=\s*\))/.source,[d]),lookbehind:!0,alias:"class-name",inside:m},"return-type":{pattern:i(/<<0>>(?=\s+(?:<<1>>\s*(?:=>|[({]|\.\s*this\s*\[)|this\s*\[))/.source,[C,S]),inside:m,alias:"class-name"},"constructor-invocation":{pattern:i(/(\bnew\s+)<<0>>(?=\s*[[({])/.source,[C]),lookbehind:!0,inside:m,alias:"class-name"},"generic-method":{pattern:i(/<<0>>\s*<<1>>(?=\s*\()/.source,[g,f]),inside:{function:i(/^<<0>>/.source,[g]),generic:{pattern:RegExp(f),alias:"class-name",inside:m}}},"type-list":{pattern:i(/\b((?:<<0>>\s+<<1>>|record\s+<<1>>\s*<<5>>|where\s+<<2>>)\s*:\s*)(?:<<3>>|<<4>>|<<1>>\s*<<5>>|<<6>>)(?:\s*,\s*(?:<<3>>|<<4>>|<<6>>))*(?=\s*(?:where|[{;]|=>|$))/.source,[s,k,g,C,u.source,d,/\bnew\s*\(\s*\)/.source]),lookbehind:!0,inside:{"record-arguments":{pattern:i(/(^(?!new\s*\()<<0>>\s*)<<1>>/.source,[k,d]),lookbehind:!0,greedy:!0,inside:n.languages.csharp},keyword:u,"class-name":{pattern:RegExp(C),greedy:!0,inside:m},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var E=j+"|"+T,R=r(/\/(?![*/])|\/\/[^\r\n]*[\r\n]|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>/.source,[E]),M=o(r(/[^"'/()]|<<0>>|\(<>*\)/.source,[R]),2),H=/\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source,P=r(/<<0>>(?:\s*\(<<1>>*\))?/.source,[S,M]);n.languages.insertBefore("csharp","class-name",{attribute:{pattern:i(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source,[H,P]),lookbehind:!0,greedy:!0,inside:{target:{pattern:i(/^<<0>>(?=\s*:)/.source,[H]),alias:"keyword"},"attribute-arguments":{pattern:i(/\(<<0>>*\)/.source,[M]),inside:n.languages.csharp},"class-name":{pattern:RegExp(S),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var z=/:[^}\r\n]+/.source,G=o(r(/[^"'/()]|<<0>>|\(<>*\)/.source,[R]),2),J=r(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[G,z]),U=o(r(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<>*\)/.source,[E]),2),ie=r(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[U,z]);function w(K,Y){return{interpolation:{pattern:i(/((?:^|[^{])(?:\{\{)*)<<0>>/.source,[K]),lookbehind:!0,inside:{"format-string":{pattern:i(/(^\{(?:(?![}:])<<0>>)*)<<1>>(?=\}$)/.source,[Y,z]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:n.languages.csharp}}},string:/[\s\S]+/}}n.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:i(/(^|[^\\])(?:\$@|@\$)"(?:""|\\[\s\S]|\{\{|<<0>>|[^\\{"])*"/.source,[J]),lookbehind:!0,greedy:!0,inside:w(J,G)},{pattern:i(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source,[ie]),lookbehind:!0,greedy:!0,inside:w(ie,U)}],char:{pattern:RegExp(T),greedy:!0}}),n.languages.dotnet=n.languages.cs=n.languages.csharp})(t)}return Dr}var Mr,Co;function vb(){if(Co)return Mr;Co=1,Mr=e,e.displayName="bash",e.aliases=["shell"];function e(t){(function(n){var r="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",i={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},o={bash:i,environment:{pattern:RegExp("\\$"+r),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+r),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};n.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+r),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:o},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:i}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:o},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:o.entity}}],environment:{pattern:RegExp("\\$?"+r),alias:"constant"},variable:o.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},i.inside=n.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],l=o.variable[1].inside,s=0;s|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),n.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var r={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:n.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete n.languages.ruby.function;var i="(?:"+[/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,/\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,/<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source].join("|")+")",o=/(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;n.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp(/%r/.source+i+/[egimnosux]{0,6}/.source),greedy:!0,inside:{interpolation:r,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:r,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp(/(^|[^:]):/.source+o),lookbehind:!0,greedy:!0},{pattern:RegExp(/([\r\n{(,][ \t]*)/.source+o+/(?=:(?!:))/.source),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),n.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp(/%[qQiIwWs]?/.source+i),greedy:!0,inside:{interpolation:r,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:r,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:r,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp(/%x/.source+i),greedy:!0,inside:{interpolation:r,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:r,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete n.languages.ruby.string,n.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),n.languages.rb=n.languages.ruby})(t)}return Fr}var zr,Ao;function Sb(){if(Ao)return zr;Ao=1,zr=e,e.displayName="diff",e.aliases=[];function e(t){(function(n){n.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var r={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(r).forEach(function(i){var o=r[i],a=[];/^\w+$/.test(i)||a.push(/\w+/.exec(i)[0]),i==="diff"&&a.push("bold"),n.languages.diff[i]={pattern:RegExp("^(?:["+o+`].*(?:\r
+`)};if(R===0){var P=p.slice(f+1,d).concat(hn({children:[H],className:m.properties.className})),z=S(P,M);c.push(z)}else if(R===A.length-1){var G=p[d+1]&&p[d+1].children&&p[d+1].children[0],J={type:"text",value:"".concat(E)};if(G){var U=hn({children:[J],className:m.properties.className});p.splice(d+1,0,U)}else{var ie=[J],w=S(ie,M,m.properties.className);c.push(w)}}else{var K=[H],Y=S(K,M,m.properties.className);c.push(Y)}}),f=d}d++};d4&&g.slice(0,4)===r&&i.test(d)&&(d.charAt(4)==="-"?k=s(d):d=u(d),S=t),new S(k,d))}function s(f){var d=f.slice(5).replace(o,c);return r+d.charAt(0).toUpperCase()+d.slice(1)}function u(f){var d=f.slice(4);return o.test(d)?f:(d=d.replace(a,p),d.charAt(0)!=="-"&&(d="-"+d),r+d)}function p(f){return"-"+f.toLowerCase()}function c(f){return f.charAt(1).toUpperCase()}return gr}var mr,ro;function rm(){if(ro)return mr;ro=1,mr=t;var e=/[#.]/g;function t(n,r){for(var i=n||"",o=r||"div",a={},l=0,s,u,p;l",Em="Í",Cm="Î",Tm="Ì",Am="Ï",Lm="<",Nm="Ñ",Im="Ó",jm="Ô",Rm="Ò",Om="Ø",Dm="Õ",Mm="Ö",Fm='"',zm="®",Pm="Þ",Bm="Ú",$m="Û",qm="Ù",Um="Ü",Hm="Ý",Wm="á",Vm="â",Gm="´",Zm="æ",Xm="à",Km="&",Ym="å",Qm="ã",Jm="ä",eb="¦",tb="ç",nb="¸",rb="¢",ib="©",ab="¤",ob="°",lb="÷",sb="é",ub="ê",cb="è",pb="ð",db="ë",fb="½",hb="¼",gb="¾",mb=">",bb="í",yb="î",xb="¡",kb="ì",vb="¿",wb="ï",Sb="«",_b="<",Eb="¯",Cb="µ",Tb="·",Ab=" ",Lb="¬",Nb="ñ",Ib="ó",jb="ô",Rb="ò",Ob="ª",Db="º",Mb="ø",Fb="õ",zb="ö",Pb="¶",Bb="±",$b="£",qb='"',Ub="»",Hb="®",Wb="§",Vb="",Gb="¹",Zb="²",Xb="³",Kb="ß",Yb="þ",Qb="×",Jb="ú",ey="û",ty="ù",ny="¨",ry="ü",iy="ý",ay="¥",oy="ÿ",ly={AElig:um,AMP:cm,Aacute:pm,Acirc:dm,Agrave:fm,Aring:hm,Atilde:gm,Auml:mm,COPY:bm,Ccedil:ym,ETH:xm,Eacute:km,Ecirc:vm,Egrave:wm,Euml:Sm,GT:_m,Iacute:Em,Icirc:Cm,Igrave:Tm,Iuml:Am,LT:Lm,Ntilde:Nm,Oacute:Im,Ocirc:jm,Ograve:Rm,Oslash:Om,Otilde:Dm,Ouml:Mm,QUOT:Fm,REG:zm,THORN:Pm,Uacute:Bm,Ucirc:$m,Ugrave:qm,Uuml:Um,Yacute:Hm,aacute:Wm,acirc:Vm,acute:Gm,aelig:Zm,agrave:Xm,amp:Km,aring:Ym,atilde:Qm,auml:Jm,brvbar:eb,ccedil:tb,cedil:nb,cent:rb,copy:ib,curren:ab,deg:ob,divide:lb,eacute:sb,ecirc:ub,egrave:cb,eth:pb,euml:db,frac12:fb,frac14:hb,frac34:gb,gt:mb,iacute:bb,icirc:yb,iexcl:xb,igrave:kb,iquest:vb,iuml:wb,laquo:Sb,lt:_b,macr:Eb,micro:Cb,middot:Tb,nbsp:Ab,not:Lb,ntilde:Nb,oacute:Ib,ocirc:jb,ograve:Rb,ordf:Ob,ordm:Db,oslash:Mb,otilde:Fb,ouml:zb,para:Pb,plusmn:Bb,pound:$b,quot:qb,raquo:Ub,reg:Hb,sect:Wb,shy:Vb,sup1:Gb,sup2:Zb,sup3:Xb,szlig:Kb,thorn:Yb,times:Qb,uacute:Jb,ucirc:ey,ugrave:ty,uml:ny,uuml:ry,yacute:iy,yen:ay,yuml:oy},sy={0:"�",128:"€",130:"‚",131:"ƒ",132:"„",133:"…",134:"†",135:"‡",136:"ˆ",137:"‰",138:"Š",139:"‹",140:"Œ",142:"Ž",145:"‘",146:"’",147:"“",148:"”",149:"•",150:"–",151:"—",152:"˜",153:"™",154:"š",155:"›",156:"œ",158:"ž",159:"Ÿ"};var kr,uo;function ss(){if(uo)return kr;uo=1,kr=e;function e(t){var n=typeof t=="string"?t.charCodeAt(0):t;return n>=48&&n<=57}return kr}var vr,co;function uy(){if(co)return vr;co=1,vr=e;function e(t){var n=typeof t=="string"?t.charCodeAt(0):t;return n>=97&&n<=102||n>=65&&n<=70||n>=48&&n<=57}return vr}var wr,po;function cy(){if(po)return wr;po=1,wr=e;function e(t){var n=typeof t=="string"?t.charCodeAt(0):t;return n>=97&&n<=122||n>=65&&n<=90}return wr}var Sr,fo;function py(){if(fo)return Sr;fo=1;var e=cy(),t=ss();Sr=n;function n(r){return e(r)||t(r)}return Sr}var _r,ho;function dy(){if(ho)return _r;ho=1;var e,t=59;_r=n;function n(r){var i="&"+r+";",o;return e=e||document.createElement("i"),e.innerHTML=i,o=e.textContent,o.charCodeAt(o.length-1)===t&&r!=="semi"||o===i?!1:o}return _r}var Er,go;function fy(){if(go)return Er;go=1;var e=ly,t=sy,n=ss(),r=uy(),i=py(),o=dy();Er=ie;var a={}.hasOwnProperty,l=String.fromCharCode,s=Function.prototype,u={warning:null,reference:null,text:null,warningContext:null,referenceContext:null,textContext:null,position:{},additional:null,attribute:!1,nonTerminated:!0},p=9,c=10,f=12,d=32,g=38,k=59,S=60,x=61,v=35,b=88,_=120,C=65533,m="named",T="hexadecimal",j="decimal",A={};A[T]=16,A[j]=10;var E={};E[m]=i,E[j]=n,E[T]=r;var R=1,M=2,H=3,P=4,z=5,G=6,J=7,U={};U[R]="Named character references must be terminated by a semicolon",U[M]="Numeric character references must be terminated by a semicolon",U[H]="Named character references cannot be empty",U[P]="Numeric character references cannot be empty",U[z]="Named character references must be known",U[G]="Numeric character references cannot be disallowed",U[J]="Numeric character references cannot be outside the permissible Unicode range";function ie(y,Z){var ee={},te,xe;Z||(Z={});for(xe in u)te=Z[xe],ee[xe]=te??u[xe];return(ee.position.indent||ee.position.start)&&(ee.indent=ee.position.indent||[],ee.position=ee.position.start),w(y,ee)}function w(y,Z){var ee=Z.additional,te=Z.nonTerminated,xe=Z.text,we=Z.reference,_e=Z.warning,Ce=Z.textContext,be=Z.referenceContext,qe=Z.warningContext,le=Z.position,ce=Z.indent||[],Ze=y.length,Ae=0,Xe=-1,Me=le.column||1,dt=le.line||1,Fe="",Qe=[],Ue,ft,He,se,L,D,B,V,re,ke,Te,ve,je,pe,Se,ze,Le,Ne,ye;for(typeof ee=="string"&&(ee=ee.charCodeAt(0)),ze=lt(),V=_e?Nn:s,Ae--,Ze++;++Ae65535&&(D-=65536,ke+=l(D>>>10|55296),D=56320|D&1023),D=ke+l(D))):pe!==m&&V(P,Ne)),D?(tn(),ze=lt(),Ae=ye-1,Me+=ye-je+1,Qe.push(D),Le=lt(),Le.offset++,we&&we.call(be,D,{start:ze,end:Le},y.slice(je-1,ye)),ze=Le):(se=y.slice(je-1,ye),Fe+=se,Me+=se.length,Ae=ye-1)}else L===10&&(dt++,Xe++,Me=0),L===L?(Fe+=l(L),Me++):tn();return Qe.join("");function lt(){return{line:dt,column:Me,offset:Ae+(le.offset||0)}}function Nn(ht,gt){var mt=lt();mt.column+=gt,mt.offset+=gt,_e.call(qe,U[ht],mt,ht)}function tn(){Fe&&(Qe.push(Fe),xe&&xe.call(Ce,Fe,{start:ze,end:lt()}),Fe="")}}function K(y){return y>=55296&&y<=57343||y>1114111}function Y(y){return y>=1&&y<=8||y===11||y>=13&&y<=31||y>=127&&y<=159||y>=64976&&y<=65007||(y&65535)===65535||(y&65535)===65534}return Er}var Cr={exports:{}},mo;function hy(){return mo||(mo=1,(function(e){var t=typeof window<"u"?window:typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?self:{};var n=(function(r){var i=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,o=0,a={},l={manual:r.Prism&&r.Prism.manual,disableWorkerMessageHandler:r.Prism&&r.Prism.disableWorkerMessageHandler,util:{encode:function v(b){return b instanceof s?new s(b.type,v(b.content),b.alias):Array.isArray(b)?b.map(v):b.replace(/&/g,"&").replace(/"u")return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(C){var v=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(C.stack)||[])[1];if(v){var b=document.getElementsByTagName("script");for(var _ in b)if(b[_].src==v)return b[_]}return null}},isActive:function(v,b,_){for(var C="no-"+b;v;){var m=v.classList;if(m.contains(b))return!0;if(m.contains(C))return!1;v=v.parentElement}return!!_}},languages:{plain:a,plaintext:a,text:a,txt:a,extend:function(v,b){var _=l.util.clone(l.languages[v]);for(var C in b)_[C]=b[C];return _},insertBefore:function(v,b,_,C){C=C||l.languages;var m=C[v],T={};for(var j in m)if(m.hasOwnProperty(j)){if(j==b)for(var A in _)_.hasOwnProperty(A)&&(T[A]=_[A]);_.hasOwnProperty(j)||(T[j]=m[j])}var E=C[v];return C[v]=T,l.languages.DFS(l.languages,function(R,M){M===E&&R!=v&&(this[R]=T)}),T},DFS:function v(b,_,C,m){m=m||{};var T=l.util.objId;for(var j in b)if(b.hasOwnProperty(j)){_.call(b,j,b[j],C||j);var A=b[j],E=l.util.type(A);E==="Object"&&!m[T(A)]?(m[T(A)]=!0,v(A,_,null,m)):E==="Array"&&!m[T(A)]&&(m[T(A)]=!0,v(A,_,j,m))}}},plugins:{},highlightAll:function(v,b){l.highlightAllUnder(document,v,b)},highlightAllUnder:function(v,b,_){var C={callback:_,container:v,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};l.hooks.run("before-highlightall",C),C.elements=Array.prototype.slice.apply(C.container.querySelectorAll(C.selector)),l.hooks.run("before-all-elements-highlight",C);for(var m=0,T;T=C.elements[m++];)l.highlightElement(T,b===!0,C.callback)},highlightElement:function(v,b,_){var C=l.util.getLanguage(v),m=l.languages[C];l.util.setLanguage(v,C);var T=v.parentElement;T&&T.nodeName.toLowerCase()==="pre"&&l.util.setLanguage(T,C);var j=v.textContent,A={element:v,language:C,grammar:m,code:j};function E(M){A.highlightedCode=M,l.hooks.run("before-insert",A),A.element.innerHTML=A.highlightedCode,l.hooks.run("after-highlight",A),l.hooks.run("complete",A),_&&_.call(A.element)}if(l.hooks.run("before-sanity-check",A),T=A.element.parentElement,T&&T.nodeName.toLowerCase()==="pre"&&!T.hasAttribute("tabindex")&&T.setAttribute("tabindex","0"),!A.code){l.hooks.run("complete",A),_&&_.call(A.element);return}if(l.hooks.run("before-highlight",A),!A.grammar){E(l.util.encode(A.code));return}if(b&&r.Worker){var R=new Worker(l.filename);R.onmessage=function(M){E(M.data)},R.postMessage(JSON.stringify({language:A.language,code:A.code,immediateClose:!0}))}else E(l.highlight(A.code,A.grammar,A.language))},highlight:function(v,b,_){var C={code:v,grammar:b,language:_};if(l.hooks.run("before-tokenize",C),!C.grammar)throw new Error('The language "'+C.language+'" has no grammar.');return C.tokens=l.tokenize(C.code,C.grammar),l.hooks.run("after-tokenize",C),s.stringify(l.util.encode(C.tokens),C.language)},tokenize:function(v,b){var _=b.rest;if(_){for(var C in _)b[C]=_[C];delete b.rest}var m=new c;return f(m,m.head,v),p(v,m,b,m.head,0),g(m)},hooks:{all:{},add:function(v,b){var _=l.hooks.all;_[v]=_[v]||[],_[v].push(b)},run:function(v,b){var _=l.hooks.all[v];if(!(!_||!_.length))for(var C=0,m;m=_[C++];)m(b)}},Token:s};r.Prism=l;function s(v,b,_,C){this.type=v,this.content=b,this.alias=_,this.length=(C||"").length|0}s.stringify=function v(b,_){if(typeof b=="string")return b;if(Array.isArray(b)){var C="";return b.forEach(function(E){C+=v(E,_)}),C}var m={type:b.type,content:v(b.content,_),tag:"span",classes:["token",b.type],attributes:{},language:_},T=b.alias;T&&(Array.isArray(T)?Array.prototype.push.apply(m.classes,T):m.classes.push(T)),l.hooks.run("wrap",m);var j="";for(var A in m.attributes)j+=" "+A+'="'+(m.attributes[A]||"").replace(/"/g,""")+'"';return"<"+m.tag+' class="'+m.classes.join(" ")+'"'+j+">"+m.content+""+m.tag+">"};function u(v,b,_,C){v.lastIndex=b;var m=v.exec(_);if(m&&C&&m[1]){var T=m[1].length;m.index+=T,m[0]=m[0].slice(T)}return m}function p(v,b,_,C,m,T){for(var j in _)if(!(!_.hasOwnProperty(j)||!_[j])){var A=_[j];A=Array.isArray(A)?A:[A];for(var E=0;E=T.reach);ie+=U.value.length,U=U.next){var w=U.value;if(b.length>v.length)return;if(!(w instanceof s)){var K=1,Y;if(P){if(Y=u(J,ie,v,H),!Y||Y.index>=v.length)break;var te=Y.index,y=Y.index+Y[0].length,Z=ie;for(Z+=U.value.length;te>=Z;)U=U.next,Z+=U.value.length;if(Z-=U.value.length,ie=Z,U.value instanceof s)continue;for(var ee=U;ee!==b.tail&&(ZT.reach&&(T.reach=Ce);var be=U.prev;we&&(be=f(b,be,we),ie+=we.length),d(b,be,K);var qe=new s(j,M?l.tokenize(xe,M):xe,z,xe);if(U=f(b,be,qe),_e&&f(b,U,_e),K>1){var le={cause:j+","+E,reach:Ce};p(v,b,_,U.prev,ie,le),T&&le.reach>T.reach&&(T.reach=le.reach)}}}}}}function c(){var v={value:null,prev:null,next:null},b={value:null,prev:v,next:null};v.next=b,this.head=v,this.tail=b,this.length=0}function f(v,b,_){var C=b.next,m={value:_,prev:b,next:C};return b.next=m,C.prev=m,v.length++,m}function d(v,b,_){for(var C=b.next,m=0;m<_&&C!==v.tail;m++)C=C.next;b.next=C,C.prev=b,v.length-=m}function g(v){for(var b=[],_=v.head.next;_!==v.tail;)b.push(_.value),_=_.next;return b}if(!r.document)return r.addEventListener&&(l.disableWorkerMessageHandler||r.addEventListener("message",function(v){var b=JSON.parse(v.data),_=b.language,C=b.code,m=b.immediateClose;r.postMessage(l.highlight(C,l.languages[_],_)),m&&r.close()},!1)),l;var k=l.util.currentScript();k&&(l.filename=k.src,k.hasAttribute("data-manual")&&(l.manual=!0));function S(){l.manual||l.highlightAll()}if(!l.manual){var x=document.readyState;x==="loading"||x==="interactive"&&k&&k.defer?document.addEventListener("DOMContentLoaded",S):window.requestAnimationFrame?window.requestAnimationFrame(S):window.setTimeout(S,16)}return l})(t);e.exports&&(e.exports=n),typeof mn<"u"&&(mn.Prism=n)})(Cr)),Cr.exports}var Tr,bo;function us(){if(bo)return Tr;bo=1,Tr=e,e.displayName="markup",e.aliases=["html","mathml","svg","xml","ssml","atom","rss"];function e(t){t.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/?[\da-f]{1,8};/i]},t.languages.markup.tag.inside["attr-value"].inside.entity=t.languages.markup.entity,t.languages.markup.doctype.inside["internal-subset"].inside=t.languages.markup,t.hooks.add("wrap",function(n){n.type==="entity"&&(n.attributes.title=n.content.value.replace(/&/,"&"))}),Object.defineProperty(t.languages.markup.tag,"addInlined",{value:function(r,i){var o={};o["language-"+i]={pattern:/(^$)/i,lookbehind:!0,inside:t.languages[i]},o.cdata=/^$/i;var a={"included-cdata":{pattern://i,inside:o}};a["language-"+i]={pattern:/[\s\S]+/,inside:t.languages[i]};var l={};l[r]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,function(){return r}),"i"),lookbehind:!0,greedy:!0,inside:a},t.languages.insertBefore("markup","cdata",l)}}),Object.defineProperty(t.languages.markup.tag,"addAttribute",{value:function(n,r){t.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+n+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[r,"language-"+r],inside:t.languages[r]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),t.languages.html=t.languages.markup,t.languages.mathml=t.languages.markup,t.languages.svg=t.languages.markup,t.languages.xml=t.languages.extend("markup",{}),t.languages.ssml=t.languages.xml,t.languages.atom=t.languages.xml,t.languages.rss=t.languages.xml}return Tr}var Ar,yo;function cs(){if(yo)return Ar;yo=1,Ar=e,e.displayName="css",e.aliases=[];function e(t){(function(n){var r=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;n.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+r.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+r.source+"$"),alias:"url"}}},selector:{pattern:RegExp(`(^|[{}\\s])[^{}\\s](?:[^{};"'\\s]|\\s+(?![\\s{])|`+r.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:r,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},n.languages.css.atrule.inside.rest=n.languages.css;var i=n.languages.markup;i&&(i.tag.addInlined("style","css"),i.tag.addAttribute("style","css"))})(t)}return Ar}var Lr,xo;function gy(){if(xo)return Lr;xo=1,Lr=e,e.displayName="clike",e.aliases=[];function e(t){t.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}}return Lr}var Nr,ko;function ps(){if(ko)return Nr;ko=1,Nr=e,e.displayName="javascript",e.aliases=["js"];function e(t){t.languages.javascript=t.languages.extend("clike",{"class-name":[t.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+(/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source)+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),t.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,t.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:t.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:t.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:t.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:t.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:t.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),t.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:t.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),t.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),t.languages.markup&&(t.languages.markup.tag.addInlined("script","javascript"),t.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),t.languages.js=t.languages.javascript}return Nr}var Ir,vo;function my(){if(vo)return Ir;vo=1;var e=typeof globalThis=="object"?globalThis:typeof self=="object"?self:typeof window=="object"?window:typeof mn=="object"?mn:{},t=C();e.Prism={manual:!0,disableWorkerMessageHandler:!0};var n=sm(),r=fy(),i=hy(),o=us(),a=cs(),l=gy(),s=ps();t();var u={}.hasOwnProperty;function p(){}p.prototype=i;var c=new p;Ir=c,c.highlight=g,c.register=f,c.alias=d,c.registered=k,c.listLanguages=S,f(o),f(a),f(l),f(s),c.util.encode=b,c.Token.stringify=x;function f(m){if(typeof m!="function"||!m.displayName)throw new Error("Expected `function` for `grammar`, got `"+m+"`");c.languages[m.displayName]===void 0&&m(c)}function d(m,T){var j=c.languages,A=m,E,R,M,H;T&&(A={},A[m]=T);for(E in A)for(R=A[E],R=typeof R=="string"?[R]:R,M=R.length,H=-1;++H?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/}}return jr}var Rr,So;function ds(){if(So)return Rr;So=1,Rr=e,e.displayName="c",e.aliases=[];function e(t){t.languages.c=t.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),t.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),t.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},t.languages.c.string],char:t.languages.c.char,comment:t.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:t.languages.c}}}}),t.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete t.languages.c.boolean}return Rr}var Or,_o;function xy(){if(_o)return Or;_o=1;var e=ds();Or=t,t.displayName="cpp",t.aliases=[];function t(n){n.register(e),(function(r){var i=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,o=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,function(){return i.source});r.languages.cpp=r.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,function(){return i.source})),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:i,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),r.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,function(){return o})+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),r.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:r.languages.cpp}}}}),r.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),r.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:r.languages.extend("cpp",{})}}),r.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},r.languages.cpp["base-clause"])})(n)}return Or}var Dr,Eo;function ky(){if(Eo)return Dr;Eo=1,Dr=e,e.displayName="csharp",e.aliases=["dotnet","cs"];function e(t){(function(n){function r(K,Y){return K.replace(/<<(\d+)>>/g,function(y,Z){return"(?:"+Y[+Z]+")"})}function i(K,Y,y){return RegExp(r(K,Y),"")}function o(K,Y){for(var y=0;y>/g,function(){return"(?:"+K+")"});return K.replace(/<>/g,"[^\\s\\S]")}var a={type:"bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",typeDeclaration:"class enum interface record struct",contextual:"add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",other:"abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield"};function l(K){return"\\b(?:"+K.trim().replace(/ /g,"|")+")\\b"}var s=l(a.typeDeclaration),u=RegExp(l(a.type+" "+a.typeDeclaration+" "+a.contextual+" "+a.other)),p=l(a.typeDeclaration+" "+a.contextual+" "+a.other),c=l(a.type+" "+a.typeDeclaration+" "+a.other),f=o(/<(?:[^<>;=+\-*/%&|^]|<>)*>/.source,2),d=o(/\((?:[^()]|<>)*\)/.source,2),g=/@?\b[A-Za-z_]\w*\b/.source,k=r(/<<0>>(?:\s*<<1>>)?/.source,[g,f]),S=r(/(?!<<0>>)<<1>>(?:\s*\.\s*<<1>>)*/.source,[p,k]),x=/\[\s*(?:,\s*)*\]/.source,v=r(/<<0>>(?:\s*(?:\?\s*)?<<1>>)*(?:\s*\?)?/.source,[S,x]),b=r(/[^,()<>[\];=+\-*/%&|^]|<<0>>|<<1>>|<<2>>/.source,[f,d,x]),_=r(/\(<<0>>+(?:,<<0>>+)+\)/.source,[b]),C=r(/(?:<<0>>|<<1>>)(?:\s*(?:\?\s*)?<<2>>)*(?:\s*\?)?/.source,[_,S,x]),m={keyword:u,punctuation:/[<>()?,.:[\]]/},T=/'(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'/.source,j=/"(?:\\.|[^\\"\r\n])*"/.source,A=/@"(?:""|\\[\s\S]|[^\\"])*"(?!")/.source;n.languages.csharp=n.languages.extend("clike",{string:[{pattern:i(/(^|[^$\\])<<0>>/.source,[A]),lookbehind:!0,greedy:!0},{pattern:i(/(^|[^@$\\])<<0>>/.source,[j]),lookbehind:!0,greedy:!0}],"class-name":[{pattern:i(/(\busing\s+static\s+)<<0>>(?=\s*;)/.source,[S]),lookbehind:!0,inside:m},{pattern:i(/(\busing\s+<<0>>\s*=\s*)<<1>>(?=\s*;)/.source,[g,C]),lookbehind:!0,inside:m},{pattern:i(/(\busing\s+)<<0>>(?=\s*=)/.source,[g]),lookbehind:!0},{pattern:i(/(\b<<0>>\s+)<<1>>/.source,[s,k]),lookbehind:!0,inside:m},{pattern:i(/(\bcatch\s*\(\s*)<<0>>/.source,[S]),lookbehind:!0,inside:m},{pattern:i(/(\bwhere\s+)<<0>>/.source,[g]),lookbehind:!0},{pattern:i(/(\b(?:is(?:\s+not)?|as)\s+)<<0>>/.source,[v]),lookbehind:!0,inside:m},{pattern:i(/\b<<0>>(?=\s+(?!<<1>>|with\s*\{)<<2>>(?:\s*[=,;:{)\]]|\s+(?:in|when)\b))/.source,[C,c,g]),inside:m}],keyword:u,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),n.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),n.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:i(/([(,]\s*)<<0>>(?=\s*:)/.source,[g]),lookbehind:!0,alias:"punctuation"}}),n.languages.insertBefore("csharp","class-name",{namespace:{pattern:i(/(\b(?:namespace|using)\s+)<<0>>(?:\s*\.\s*<<0>>)*(?=\s*[;{])/.source,[g]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:i(/(\b(?:default|sizeof|typeof)\s*\(\s*(?!\s))(?:[^()\s]|\s(?!\s)|<<0>>)*(?=\s*\))/.source,[d]),lookbehind:!0,alias:"class-name",inside:m},"return-type":{pattern:i(/<<0>>(?=\s+(?:<<1>>\s*(?:=>|[({]|\.\s*this\s*\[)|this\s*\[))/.source,[C,S]),inside:m,alias:"class-name"},"constructor-invocation":{pattern:i(/(\bnew\s+)<<0>>(?=\s*[[({])/.source,[C]),lookbehind:!0,inside:m,alias:"class-name"},"generic-method":{pattern:i(/<<0>>\s*<<1>>(?=\s*\()/.source,[g,f]),inside:{function:i(/^<<0>>/.source,[g]),generic:{pattern:RegExp(f),alias:"class-name",inside:m}}},"type-list":{pattern:i(/\b((?:<<0>>\s+<<1>>|record\s+<<1>>\s*<<5>>|where\s+<<2>>)\s*:\s*)(?:<<3>>|<<4>>|<<1>>\s*<<5>>|<<6>>)(?:\s*,\s*(?:<<3>>|<<4>>|<<6>>))*(?=\s*(?:where|[{;]|=>|$))/.source,[s,k,g,C,u.source,d,/\bnew\s*\(\s*\)/.source]),lookbehind:!0,inside:{"record-arguments":{pattern:i(/(^(?!new\s*\()<<0>>\s*)<<1>>/.source,[k,d]),lookbehind:!0,greedy:!0,inside:n.languages.csharp},keyword:u,"class-name":{pattern:RegExp(C),greedy:!0,inside:m},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var E=j+"|"+T,R=r(/\/(?![*/])|\/\/[^\r\n]*[\r\n]|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>/.source,[E]),M=o(r(/[^"'/()]|<<0>>|\(<>*\)/.source,[R]),2),H=/\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source,P=r(/<<0>>(?:\s*\(<<1>>*\))?/.source,[S,M]);n.languages.insertBefore("csharp","class-name",{attribute:{pattern:i(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source,[H,P]),lookbehind:!0,greedy:!0,inside:{target:{pattern:i(/^<<0>>(?=\s*:)/.source,[H]),alias:"keyword"},"attribute-arguments":{pattern:i(/\(<<0>>*\)/.source,[M]),inside:n.languages.csharp},"class-name":{pattern:RegExp(S),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var z=/:[^}\r\n]+/.source,G=o(r(/[^"'/()]|<<0>>|\(<>*\)/.source,[R]),2),J=r(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[G,z]),U=o(r(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<>*\)/.source,[E]),2),ie=r(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[U,z]);function w(K,Y){return{interpolation:{pattern:i(/((?:^|[^{])(?:\{\{)*)<<0>>/.source,[K]),lookbehind:!0,inside:{"format-string":{pattern:i(/(^\{(?:(?![}:])<<0>>)*)<<1>>(?=\}$)/.source,[Y,z]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:n.languages.csharp}}},string:/[\s\S]+/}}n.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:i(/(^|[^\\])(?:\$@|@\$)"(?:""|\\[\s\S]|\{\{|<<0>>|[^\\{"])*"/.source,[J]),lookbehind:!0,greedy:!0,inside:w(J,G)},{pattern:i(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source,[ie]),lookbehind:!0,greedy:!0,inside:w(ie,U)}],char:{pattern:RegExp(T),greedy:!0}}),n.languages.dotnet=n.languages.cs=n.languages.csharp})(t)}return Dr}var Mr,Co;function vy(){if(Co)return Mr;Co=1,Mr=e,e.displayName="bash",e.aliases=["shell"];function e(t){(function(n){var r="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",i={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},o={bash:i,environment:{pattern:RegExp("\\$"+r),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+r),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};n.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+r),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:o},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:i}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:o},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:o.entity}}],environment:{pattern:RegExp("\\$?"+r),alias:"constant"},variable:o.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},i.inside=n.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],l=o.variable[1].inside,s=0;s|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),n.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var r={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:n.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete n.languages.ruby.function;var i="(?:"+[/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,/\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,/<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source].join("|")+")",o=/(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;n.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp(/%r/.source+i+/[egimnosux]{0,6}/.source),greedy:!0,inside:{interpolation:r,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:r,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp(/(^|[^:]):/.source+o),lookbehind:!0,greedy:!0},{pattern:RegExp(/([\r\n{(,][ \t]*)/.source+o+/(?=:(?!:))/.source),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),n.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp(/%[qQiIwWs]?/.source+i),greedy:!0,inside:{interpolation:r,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:r,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:r,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp(/%x/.source+i),greedy:!0,inside:{interpolation:r,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:r,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete n.languages.ruby.string,n.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),n.languages.rb=n.languages.ruby})(t)}return Fr}var zr,Ao;function Sy(){if(Ao)return zr;Ao=1,zr=e,e.displayName="diff",e.aliases=[];function e(t){(function(n){n.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var r={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(r).forEach(function(i){var o=r[i],a=[];/^\w+$/.test(i)||a.push(/\w+/.exec(i)[0]),i==="diff"&&a.push("bold"),n.languages.diff[i]={pattern:RegExp("^(?:["+o+`].*(?:\r
?|
-|(?![\\s\\S])))+`,"m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(i)[0]}}}}),Object.defineProperty(n.languages.diff,"PREFIXES",{value:r})})(t)}return zr}var Pr,Lo;function _b(){if(Lo)return Pr;Lo=1,Pr=e,e.displayName="markupTemplating",e.aliases=[];function e(t){(function(n){function r(i,o){return"___"+i.toUpperCase()+o+"___"}Object.defineProperties(n.languages["markup-templating"]={},{buildPlaceholders:{value:function(i,o,a,l){if(i.language===o){var s=i.tokenStack=[];i.code=i.code.replace(a,function(u){if(typeof l=="function"&&!l(u))return u;for(var p=s.length,c;i.code.indexOf(c=r(o,p))!==-1;)++p;return s[p]=u,c}),i.grammar=n.languages.markup}}},tokenizePlaceholders:{value:function(i,o){if(i.language!==o||!i.tokenStack)return;i.grammar=n.languages[o];var a=0,l=Object.keys(i.tokenStack);function s(u){for(var p=0;p=l.length);p++){var c=u[p];if(typeof c=="string"||c.content&&typeof c.content=="string"){var f=l[a],d=i.tokenStack[f],g=typeof c=="string"?c:c.content,k=r(o,f),S=g.indexOf(k);if(S>-1){++a;var x=g.substring(0,S),v=new n.Token(o,n.tokenize(d,i.grammar),"language-"+o,d),y=g.substring(S+k.length),_=[];x&&_.push.apply(_,s([x])),_.push(v),y&&_.push.apply(_,s([y])),typeof c=="string"?u.splice.apply(u,[p,1].concat(_)):c.content=_}}else c.content&&s(c.content)}return u}s(i.tokens)}}})})(t)}return Pr}var Br,No;function Eb(){if(No)return Br;No=1,Br=e,e.displayName="go",e.aliases=[];function e(t){t.languages.go=t.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),t.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete t.languages.go["class-name"]}return Br}var $r,Io;function Cb(){if(Io)return $r;Io=1,$r=e,e.displayName="java",e.aliases=[];function e(t){(function(n){var r=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,i=/(^|[^\w.])(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,o={pattern:RegExp(i+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};n.languages.java=n.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[o,{pattern:RegExp(i+/[A-Z]\w*(?=\s+\w+\s*[;,=()])/.source),lookbehind:!0,inside:o.inside}],keyword:r,function:[n.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),n.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),n.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":o,keyword:r,punctuation:/[<>(),.:]/,operator:/[?&|]/}},namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(//g,function(){return r.source})),lookbehind:!0,inside:{punctuation:/\./}}})})(t)}return $r}var qr,jo;function fs(){if(jo)return qr;jo=1,qr=e,e.displayName="typescript",e.aliases=["ts"];function e(t){(function(n){n.languages.typescript=n.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),n.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete n.languages.typescript.parameter,delete n.languages.typescript["literal-property"];var r=n.languages.extend("typescript",{});delete r["class-name"],n.languages.typescript["class-name"].inside=r,n.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:r}}}}),n.languages.ts=n.languages.typescript})(t)}return qr}var Ur,Ro;function Tb(){if(Ro)return Ur;Ro=1,Ur=e,e.displayName="json",e.aliases=["webmanifest"];function e(t){t.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},t.languages.webmanifest=t.languages.json}return Ur}var Hr,Oo;function hs(){if(Oo)return Hr;Oo=1,Hr=e,e.displayName="jsx",e.aliases=[];function e(t){(function(n){var r=n.util.clone(n.languages.javascript),i=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,o=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,a=/(?:\{*\.{3}(?:[^{}]|)*\})/.source;function l(p,c){return p=p.replace(//g,function(){return i}).replace(//g,function(){return o}).replace(//g,function(){return a}),RegExp(p,c)}a=l(a).source,n.languages.jsx=n.languages.extend("markup",r),n.languages.jsx.tag.pattern=l(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),n.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,n.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,n.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,n.languages.jsx.tag.inside.comment=r.comment,n.languages.insertBefore("inside","attr-name",{spread:{pattern:l(//.source),inside:n.languages.jsx}},n.languages.jsx.tag),n.languages.insertBefore("inside","special-attr",{script:{pattern:l(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:n.languages.jsx}}},n.languages.jsx.tag);var s=function(p){return p?typeof p=="string"?p:typeof p.content=="string"?p.content:p.content.map(s).join(""):""},u=function(p){for(var c=[],f=0;f0&&c[c.length-1].tagName===s(d.content[0].content[1])&&c.pop():d.content[d.content.length-1].content==="/>"||c.push({tagName:s(d.content[0].content[1]),openedBraces:0}):c.length>0&&d.type==="punctuation"&&d.content==="{"?c[c.length-1].openedBraces++:c.length>0&&c[c.length-1].openedBraces>0&&d.type==="punctuation"&&d.content==="}"?c[c.length-1].openedBraces--:g=!0),(g||typeof d=="string")&&c.length>0&&c[c.length-1].openedBraces===0){var k=s(d);f0&&(typeof p[f-1]=="string"||p[f-1].type==="plain-text")&&(k=s(p[f-1])+k,p.splice(f-1,1),f--),p[f]=new n.Token("plain-text",k,null,k)}d.content&&typeof d.content!="string"&&u(d.content)}};n.hooks.add("after-tokenize",function(p){p.language!=="jsx"&&p.language!=="tsx"||u(p.tokens)})})(t)}return Hr}var Wr,Do;function Ab(){if(Do)return Wr;Do=1,Wr=e,e.displayName="kotlin",e.aliases=["kt","kts"];function e(t){(function(n){n.languages.kotlin=n.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete n.languages.kotlin["class-name"];var r={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:n.languages.kotlin}};n.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:r},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:r},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete n.languages.kotlin.string,n.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),n.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),n.languages.kt=n.languages.kotlin,n.languages.kts=n.languages.kotlin})(t)}return Wr}var Vr,Mo;function Lb(){if(Mo)return Vr;Mo=1;var e=_b();Vr=t,t.displayName="php",t.aliases=[];function t(n){n.register(e),(function(r){var i=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,o=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],a=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,l=/=>|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,s=/[{}\[\](),:;]/;r.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:i,variable:/\$+(?:\w+\b|(?=\{))/,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},"function-definition":{pattern:/(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,lookbehind:!0,alias:"function"},keyword:[{pattern:/(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string|void)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(\byield\s+)from\b/i,lookbehind:!0},/\bclass\b/i,{pattern:/((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|new|or|parent|print|private|protected|public|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i,lookbehind:!0}],"argument-name":{pattern:/([(,]\s+)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:o,function:{pattern:/(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,lookbehind:!0,inside:{punctuation:/\\/}},property:{pattern:/(->\s*)\w+/,lookbehind:!0},number:a,operator:l,punctuation:s};var u={pattern:/\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,lookbehind:!0,inside:r.languages.php},p=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:u}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:u}}];r.languages.insertBefore("php","variable",{string:p,attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=\]$)/,lookbehind:!0,inside:{comment:i,string:p,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:o,number:a,operator:l,punctuation:s}},delimiter:{pattern:/^#\[|\]$/,alias:"punctuation"}}}}),r.hooks.add("before-tokenize",function(c){if(/<\?/.test(c.code)){var f=/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g;r.languages["markup-templating"].buildPlaceholders(c,"php",f)}}),r.hooks.add("after-tokenize",function(c){r.languages["markup-templating"].tokenizePlaceholders(c,"php")})})(n)}return Vr}var Gr,Fo;function Nb(){if(Fo)return Gr;Fo=1,Gr=e,e.displayName="markdown",e.aliases=["md"];function e(t){(function(n){var r=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function i(f){return f=f.replace(//g,function(){return r}),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+f+")")}var o=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,function(){return o}),l=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;n.languages.markdown=n.languages.extend("markup",{}),n.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:n.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+l+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+l+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(o),inside:n.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+l+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(o),alias:"important",inside:n.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:i(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:i(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:i(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:i(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach(function(f){["url","bold","italic","strike","code-snippet"].forEach(function(d){f!==d&&(n.languages.markdown[f].inside.content.inside[d]=n.languages.markdown[d])})}),n.hooks.add("after-tokenize",function(f){if(f.language!=="markdown"&&f.language!=="md")return;function d(g){if(!(!g||typeof g=="string"))for(var k=0,S=g.length;k",quot:'"'},p=String.fromCodePoint||String.fromCharCode;function c(f){var d=f.replace(s,"");return d=d.replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,function(g,k){if(k=k.toLowerCase(),k[0]==="#"){var S;return k[1]==="x"?S=parseInt(k.slice(2),16):S=Number(k.slice(1)),p(S)}else{var x=u[k];return x||g}}),d}n.languages.md=n.languages.markdown})(t)}return Gr}var Zr,zo;function Ib(){if(zo)return Zr;zo=1,Zr=e,e.displayName="python",e.aliases=["py"];function e(t){t.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern://,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},t.languages.python["string-interpolation"].inside.interpolation.inside.rest=t.languages.python,t.languages.py=t.languages.python}return Zr}var Xr,Po;function jb(){if(Po)return Xr;Po=1,Xr=e,e.displayName="rust",e.aliases=[];function e(t){(function(n){for(var r=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|)*\*\//.source,i=0;i<2;i++)r=r.replace(//g,function(){return r});r=r.replace(//g,function(){return/[^\s\S]/.source}),n.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+r),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<=?|>>?=?|[@?]/},n.languages.rust["closure-params"].inside.rest=n.languages.rust,n.languages.rust.attribute.inside.string=n.languages.rust.string})(t)}return Xr}var Kr,Bo;function Rb(){if(Bo)return Kr;Bo=1,Kr=e,e.displayName="swift",e.aliases=[];function e(t){t.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+(/(?:elseif|if)\b/.source+"(?:[ ]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+")+"|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},t.languages.swift["string-literal"].forEach(function(n){n.inside.interpolation.inside=t.languages.swift})}return Kr}var Yr,$o;function Ob(){if($o)return Yr;$o=1,Yr=e,e.displayName="yaml",e.aliases=["yml"];function e(t){(function(n){var r=/[*&][^\s[\]{},]+/,i=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,o="(?:"+i.source+"(?:[ ]+"+r.source+")?|"+r.source+"(?:[ ]+"+i.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source}),l=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function s(u,p){p=(p||"").replace(/m/g,"")+"m";var c=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,function(){return o}).replace(/<>/g,function(){return u});return RegExp(c,p)}n.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,function(){return o})),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,function(){return o}).replace(/<>/g,function(){return"(?:"+a+"|"+l+")"})),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:s(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:s(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:s(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:s(l),lookbehind:!0,greedy:!0},number:{pattern:s(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:i,important:r,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},n.languages.yml=n.languages.yaml})(t)}return Yr}var Qr,qo;function Db(){if(qo)return Qr;qo=1;var e=hs(),t=fs();Qr=n,n.displayName="tsx",n.aliases=[];function n(r){r.register(e),r.register(t),(function(i){var o=i.util.clone(i.languages.typescript);i.languages.tsx=i.languages.extend("jsx",o),delete i.languages.tsx.parameter,delete i.languages.tsx["literal-property"];var a=i.languages.tsx.tag;a.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+a.pattern.source+")",a.pattern.flags),a.lookbehind=!0})(r)}return Qr}const Mb={'code[class*="language-"]':{color:"#393A34",fontFamily:'"Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace',direction:"ltr",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",fontSize:".9em",lineHeight:"1.2em",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none"},'pre[class*="language-"]':{color:"#393A34",fontFamily:'"Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace',direction:"ltr",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",fontSize:".9em",lineHeight:"1.2em",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none",padding:"1em",margin:".5em 0",overflow:"auto",border:"1px solid #dddddd",backgroundColor:"white"},'pre > code[class*="language-"]':{fontSize:"1em"},'pre[class*="language-"]::-moz-selection':{background:"#C1DEF1"},'pre[class*="language-"] ::-moz-selection':{background:"#C1DEF1"},'code[class*="language-"]::-moz-selection':{background:"#C1DEF1"},'code[class*="language-"] ::-moz-selection':{background:"#C1DEF1"},'pre[class*="language-"]::selection':{background:"#C1DEF1"},'pre[class*="language-"] ::selection':{background:"#C1DEF1"},'code[class*="language-"]::selection':{background:"#C1DEF1"},'code[class*="language-"] ::selection':{background:"#C1DEF1"},':not(pre) > code[class*="language-"]':{padding:".2em",paddingTop:"1px",paddingBottom:"1px",background:"#f8f8f8",border:"1px solid #dddddd"},comment:{color:"#008000",fontStyle:"italic"},prolog:{color:"#008000",fontStyle:"italic"},doctype:{color:"#008000",fontStyle:"italic"},cdata:{color:"#008000",fontStyle:"italic"},namespace:{Opacity:".7"},string:{color:"#A31515"},punctuation:{color:"#393A34"},operator:{color:"#393A34"},url:{color:"#36acaa"},symbol:{color:"#36acaa"},number:{color:"#36acaa"},boolean:{color:"#36acaa"},variable:{color:"#36acaa"},constant:{color:"#36acaa"},inserted:{color:"#36acaa"},atrule:{color:"#0000ff"},keyword:{color:"#0000ff"},"attr-value":{color:"#0000ff"},".language-autohotkey .token.selector":{color:"#0000ff"},".language-json .token.boolean":{color:"#0000ff"},".language-json .token.number":{color:"#0000ff"},'code[class*="language-css"]':{color:"#0000ff"},function:{color:"#393A34"},deleted:{color:"#9a050f"},".language-autohotkey .token.tag":{color:"#9a050f"},selector:{color:"#800000"},".language-autohotkey .token.keyword":{color:"#00009f"},important:{color:"#e90",fontWeight:"bold"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"},"class-name":{color:"#2B91AF"},".language-json .token.property":{color:"#2B91AF"},tag:{color:"#800000"},"attr-name":{color:"#ff0000"},property:{color:"#ff0000"},regex:{color:"#ff0000"},entity:{color:"#ff0000"},"directive.tag.tag":{background:"#ffff00",color:"#393A34"},".line-numbers.line-numbers .line-numbers-rows":{borderRightColor:"#a5a5a5"},".line-numbers .line-numbers-rows > span:before":{color:"#2B91AF"},".line-highlight.line-highlight":{background:"linear-gradient(to right, rgba(193, 222, 241, 0.2) 70%, rgba(221, 222, 241, 0))"}},Fb={'pre[class*="language-"]':{color:"#d4d4d4",fontSize:"13px",textShadow:"none",fontFamily:'Menlo, Monaco, Consolas, "Andale Mono", "Ubuntu Mono", "Courier New", monospace',direction:"ltr",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",lineHeight:"1.5",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none",padding:"1em",margin:".5em 0",overflow:"auto",background:"#1e1e1e"},'code[class*="language-"]':{color:"#d4d4d4",fontSize:"13px",textShadow:"none",fontFamily:'Menlo, Monaco, Consolas, "Andale Mono", "Ubuntu Mono", "Courier New", monospace',direction:"ltr",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",lineHeight:"1.5",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none"},'pre[class*="language-"]::selection':{textShadow:"none",background:"#264F78"},'code[class*="language-"]::selection':{textShadow:"none",background:"#264F78"},'pre[class*="language-"] *::selection':{textShadow:"none",background:"#264F78"},'code[class*="language-"] *::selection':{textShadow:"none",background:"#264F78"},':not(pre) > code[class*="language-"]':{padding:".1em .3em",borderRadius:".3em",color:"#db4c69",background:"#1e1e1e"},".namespace":{Opacity:".7"},"doctype.doctype-tag":{color:"#569CD6"},"doctype.name":{color:"#9cdcfe"},comment:{color:"#6a9955"},prolog:{color:"#6a9955"},punctuation:{color:"#d4d4d4"},".language-html .language-css .token.punctuation":{color:"#d4d4d4"},".language-html .language-javascript .token.punctuation":{color:"#d4d4d4"},property:{color:"#9cdcfe"},tag:{color:"#569cd6"},boolean:{color:"#569cd6"},number:{color:"#b5cea8"},constant:{color:"#9cdcfe"},symbol:{color:"#b5cea8"},inserted:{color:"#b5cea8"},unit:{color:"#b5cea8"},selector:{color:"#d7ba7d"},"attr-name":{color:"#9cdcfe"},string:{color:"#ce9178"},char:{color:"#ce9178"},builtin:{color:"#ce9178"},deleted:{color:"#ce9178"},".language-css .token.string.url":{textDecoration:"underline"},operator:{color:"#d4d4d4"},entity:{color:"#569cd6"},"operator.arrow":{color:"#569CD6"},atrule:{color:"#ce9178"},"atrule.rule":{color:"#c586c0"},"atrule.url":{color:"#9cdcfe"},"atrule.url.function":{color:"#dcdcaa"},"atrule.url.punctuation":{color:"#d4d4d4"},keyword:{color:"#569CD6"},"keyword.module":{color:"#c586c0"},"keyword.control-flow":{color:"#c586c0"},function:{color:"#dcdcaa"},"function.maybe-class-name":{color:"#dcdcaa"},regex:{color:"#d16969"},important:{color:"#569cd6"},italic:{fontStyle:"italic"},"class-name":{color:"#4ec9b0"},"maybe-class-name":{color:"#4ec9b0"},console:{color:"#9cdcfe"},parameter:{color:"#9cdcfe"},interpolation:{color:"#9cdcfe"},"punctuation.interpolation-punctuation":{color:"#569cd6"},variable:{color:"#9cdcfe"},"imports.maybe-class-name":{color:"#9cdcfe"},"exports.maybe-class-name":{color:"#9cdcfe"},escape:{color:"#d7ba7d"},"tag.punctuation":{color:"#808080"},cdata:{color:"#808080"},"attr-value":{color:"#ce9178"},"attr-value.punctuation":{color:"#ce9178"},"attr-value.punctuation.attr-equals":{color:"#d4d4d4"},namespace:{color:"#4ec9b0"},'pre[class*="language-javascript"]':{color:"#9cdcfe"},'code[class*="language-javascript"]':{color:"#9cdcfe"},'pre[class*="language-jsx"]':{color:"#9cdcfe"},'code[class*="language-jsx"]':{color:"#9cdcfe"},'pre[class*="language-typescript"]':{color:"#9cdcfe"},'code[class*="language-typescript"]':{color:"#9cdcfe"},'pre[class*="language-tsx"]':{color:"#9cdcfe"},'code[class*="language-tsx"]':{color:"#9cdcfe"},'pre[class*="language-css"]':{color:"#ce9178"},'code[class*="language-css"]':{color:"#ce9178"},'pre[class*="language-html"]':{color:"#d4d4d4"},'code[class*="language-html"]':{color:"#d4d4d4"},".language-regex .token.anchor":{color:"#dcdcaa"},".language-html .token.punctuation":{color:"#808080"},'pre[class*="language-"] > code[class*="language-"]':{position:"relative",zIndex:"1"},".line-highlight.line-highlight":{background:"#f7ebc6",boxShadow:"inset 5px 0 0 #f7d87c",zIndex:"0"}};var zb=vb();const gs=me(zb);var Pb=ds();const Bb=me(Pb);var $b=xb();const qb=me($b);var Ub=kb();const ms=me(Ub);var Hb=cs();const Wb=me(Hb);var Vb=Sb();const Gb=me(Vb);var Zb=Eb();const Xb=me(Zb);var Kb=Cb();const Yb=me(Kb);var Qb=ps();const ys=me(Qb);var Jb=Tb();const ex=me(Jb);var tx=hs();const nx=me(tx);var rx=Ab();const ix=me(rx);var ax=Nb();const bs=me(ax);var ox=us();const Ui=me(ox);var lx=Lb();const sx=me(lx);var ux=Ib();const xs=me(ux);var cx=wb();const ks=me(cx);var px=jb();const dx=me(px);var fx=bb();const hx=me(fx);var gx=Rb();const mx=me(gx);var yx=Db();const bx=me(yx);var xx=fs();const vs=me(xx);var kx=Ob();const ws=me(kx);function Je(e,t){Ks(e)||t(e instanceof Error?e.message:String(e))}const vx={bash:gs,c:Bb,cpp:qb,csharp:ms,css:Wb,diff:Gb,go:Xb,java:Yb,javascript:ys,json:ex,jsx:nx,kotlin:ix,markdown:bs,markup:Ui,php:sx,python:xs,ruby:ks,rust:dx,sql:hx,swift:mx,tsx:bx,typescript:vs,yaml:ws};Object.entries(vx).forEach(([e,t])=>{$e.registerLanguage(e,t)});$e.registerLanguage("cs",ms);$e.registerLanguage("html",Ui);$e.registerLanguage("js",ys);$e.registerLanguage("md",bs);$e.registerLanguage("py",xs);$e.registerLanguage("rb",ks);$e.registerLanguage("sh",gs);$e.registerLanguage("ts",vs);$e.registerLanguage("xml",Ui);$e.registerLanguage("yml",ws);function Wt(e){return e<1e3?`${Math.round(e)}ms`:`${(e/1e3).toFixed(1)}s`}function Hi(e,t){return e==="en-US"&&t!==1?"s":""}function wx(e,t){if(!e||e.length<=t)return e;const n=t-3,r=Math.ceil(n*.6),i=n-r;return e.slice(0,r)+"..."+e.slice(-i)}function Jr(e){return e.replace(/#img:\S+\s*/g,"").replace(/\[Image:.*?\]\n(?:Path:.*?\n|Image ID:.*?\n)?/g,"").trim()}function Ss(e){if(navigator.clipboard?.writeText)return navigator.clipboard.writeText(e);const t=document.createElement("textarea");t.value=e,t.style.cssText="position:fixed;left:-9999px;top:-9999px;opacity:0",document.body.appendChild(t),t.select();try{document.execCommand("copy")}finally{document.body.removeChild(t)}return Promise.resolve()}const Sx=({code:e})=>{const[t,n]=N.useState(!1),r=async()=>{try{await Ss(e),n(!0),setTimeout(()=>n(!1),2e3)}catch{}};return h.jsx("button",{className:`copy-button${t?" copy-success":""}`,onClick:r,type:"button",children:t?h.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("polyline",{points:"20 6 9 17 4 12"})}):h.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),h.jsx("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})})},vn="computer://",yi="file://",Uo="{{workspaceFolder}}",bi="bitfun.mobile.last_selected_model_id",_x=new Set(["js","jsx","ts","tsx","mjs","cjs","mts","cts","py","pyw","pyi","rs","go","java","kt","kts","scala","groovy","c","cpp","cc","cxx","h","hpp","hxx","hh","cs","rb","php","swift","vue","svelte","css","scss","less","sass","json","jsonc","yaml","yml","toml","xml","md","mdx","rst","txt","sh","bash","zsh","fish","ps1","bat","cmd","sql","graphql","gql","proto","lock","env","ini","cfg","conf","cj","ets","editorconfig","gitignore","log"]),Ex=new Set(["pdf","doc","docx","xls","xlsx","ppt","pptx","odt","ods","odp","rtf","pages","numbers","key","png","jpg","jpeg","gif","bmp","svg","webp","ico","tiff","tif","zip","tar","gz","bz2","7z","rar","dmg","iso","xz","mp3","wav","ogg","flac","aac","m4a","wma","mp4","avi","mkv","mov","webm","wmv","flv","csv","tsv","sqlite","db","parquet","epub","mobi","apk","ipa","exe","msi","deb","rpm","ttf","otf","woff","woff2"]);function wn(e){let t=e;e.startsWith(vn)?t=e.slice(vn.length):e.startsWith(yi)?t=e.slice(yi.length):e.startsWith("file:")&&(t=e.slice(5)),t.startsWith(Uo)&&(t=t.slice(Uo.length),t.startsWith("/")&&(t=t.slice(1))),/^\/[A-Za-z]:[\\/]/.test(t)&&(t=t.slice(1));try{return decodeURIComponent(t)}catch{return t}}function Cx(e){if(!e||e==="/")return null;let t;if(e.startsWith(vn)||e.startsWith(yi)||e.startsWith("file:"))t=wn(e);else{if(e.includes("://")||e.startsWith("#")||e.startsWith("//"))return null;t=wn(e)}if(t.startsWith("/")&&t.split("/").filter(Boolean).length<2)return null;const n=t.split("/").pop()||"",r=n.lastIndexOf(".");if(r<=0)return null;const i=n.slice(r+1).toLowerCase();if(!i)return null;if(t.startsWith("/")){if(_x.has(i))return null}else if(!Ex.has(i))return null;return t}function Tx(e){return e>=1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:e>=1024?`${Math.round(e/1024)} KB`:`${e} B`}const ei=({size:e=20,style:t})=>h.jsxs("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:t,"aria-hidden":"true",children:[h.jsx("path",{d:"M15.3929 4.05365L14.8912 4.61112L15.3929 4.05365ZM19.3517 7.61654L18.85 8.17402L19.3517 7.61654ZM21.654 10.1541L20.9689 10.4592V10.4592L21.654 10.1541ZM3.17157 20.8284L3.7019 20.2981H3.7019L3.17157 20.8284ZM20.8284 20.8284L20.2981 20.2981L20.2981 20.2981L20.8284 20.8284ZM14 21.25H10V22.75H14V21.25ZM2.75 14V10H1.25V14H2.75ZM21.25 13.5629V14H22.75V13.5629H21.25ZM14.8912 4.61112L18.85 8.17402L19.8534 7.05907L15.8947 3.49618L14.8912 4.61112ZM22.75 13.5629C22.75 11.8745 22.7651 10.8055 22.3391 9.84897L20.9689 10.4592C21.2349 11.0565 21.25 11.742 21.25 13.5629H22.75ZM18.85 8.17402C20.2034 9.3921 20.7029 9.86199 20.9689 10.4592L22.3391 9.84897C21.9131 8.89241 21.1084 8.18853 19.8534 7.05907L18.85 8.17402ZM10.0298 2.75C11.6116 2.75 12.2085 2.76158 12.7405 2.96573L13.2779 1.5653C12.4261 1.23842 11.498 1.25 10.0298 1.25V2.75ZM15.8947 3.49618C14.8087 2.51878 14.1297 1.89214 13.2779 1.5653L12.7405 2.96573C13.2727 3.16993 13.7215 3.55836 14.8912 4.61112L15.8947 3.49618ZM10 21.25C8.09318 21.25 6.73851 21.2484 5.71085 21.1102C4.70476 20.975 4.12511 20.7213 3.7019 20.2981L2.64124 21.3588C3.38961 22.1071 4.33855 22.4392 5.51098 22.5969C6.66182 22.7516 8.13558 22.75 10 22.75V21.25ZM1.25 14C1.25 15.8644 1.24841 17.3382 1.40313 18.489C1.56076 19.6614 1.89288 20.6104 2.64124 21.3588L3.7019 20.2981C3.27869 19.8749 3.02502 19.2952 2.88976 18.2892C2.75159 17.2615 2.75 15.9068 2.75 14H1.25ZM14 22.75C15.8644 22.75 17.3382 22.7516 18.489 22.5969C19.6614 22.4392 20.6104 22.1071 21.3588 21.3588L20.2981 20.2981C19.8749 20.7213 19.2952 20.975 18.2892 21.1102C17.2615 21.2484 15.9068 21.25 14 21.25V22.75ZM21.25 14C21.25 15.9068 21.2484 17.2615 21.1102 18.2892C20.975 19.2952 20.7213 19.8749 20.2981 20.2981L21.3588 21.3588C22.1071 20.6104 22.4392 19.6614 22.5969 18.489C22.7516 17.3382 22.75 15.8644 22.75 14H21.25ZM2.75 10C2.75 8.09318 2.75159 6.73851 2.88976 5.71085C3.02502 4.70476 3.27869 4.12511 3.7019 3.7019L2.64124 2.64124C1.89288 3.38961 1.56076 4.33855 1.40313 5.51098C1.24841 6.66182 1.25 8.13558 1.25 10H2.75ZM10.0298 1.25C8.15538 1.25 6.67442 1.24842 5.51887 1.40307C4.34232 1.56054 3.39019 1.8923 2.64124 2.64124L3.7019 3.7019C4.12453 3.27928 4.70596 3.02525 5.71785 2.88982C6.75075 2.75158 8.11311 2.75 10.0298 2.75V1.25Z",fill:"currentColor"}),h.jsx("path",{d:"M6 14.5H14",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),h.jsx("path",{d:"M6 18H11.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),h.jsx("path",{d:"M13 2.5V5C13 7.35702 13 8.53553 13.7322 9.26777C14.4645 10 15.643 10 18 10H22",stroke:"currentColor",strokeWidth:"1.5"})]}),Ho=({path:e,onGetFileInfo:t,onDownload:n})=>{const{t:r}=Ye(),[i,o]=N.useState({status:"loading"}),a=N.useRef(t);a.current=t,N.useEffect(()=>{let g=!1;return a.current(e).then(({name:k,size:S,mimeType:x})=>{g||o({status:"ready",name:k,size:S,mimeType:x})}).catch(k=>{g||o({status:"error",message:k instanceof Error?k.message:String(k)})}),()=>{g=!0}},[e]);const l=N.useCallback(async()=>{if(i.status!=="ready"&&i.status!=="done")return;const g=i;o({status:"downloading",name:g.name,size:g.size,mimeType:g.mimeType,progress:0});try{await n(e,(k,S)=>{o(x=>x.status!=="downloading"?x:{...x,progress:S>0?k/S:0})}),o({status:"done",name:g.name,size:g.size,mimeType:g.mimeType})}catch{o({status:"ready",name:g.name,size:g.size,mimeType:g.mimeType})}},[i,e,n]),s={display:"inline-flex",alignItems:"center",gap:"10px",padding:"10px 14px",border:"1px solid var(--border-subtle)",borderRadius:"10px",background:"var(--element-bg-subtle)",cursor:i.status==="ready"||i.status==="done"?"pointer":"default",maxWidth:"300px",verticalAlign:"middle",transition:"background 0.15s"},u="var(--color-text-muted)";if(i.status==="loading")return h.jsxs("span",{className:"file-card",style:s,children:[h.jsx(ei,{size:20,style:{color:u,flexShrink:0}}),h.jsx("span",{style:{fontSize:"0.8rem",opacity:.5},children:r("chat.fileLoading")})]});if(i.status==="error")return h.jsxs("span",{className:"file-card",style:{...s,cursor:"default",opacity:.5},title:i.message,children:[h.jsx(ei,{size:20,style:{color:u,flexShrink:0}}),h.jsx("span",{style:{fontSize:"0.8rem"},children:r("chat.fileUnavailable")})]});const{name:p,size:c}=i,f=i.status==="downloading",d=i.status==="done";return h.jsxs("span",{className:"file-card",style:s,onClick:l,role:"button",tabIndex:0,onKeyDown:g=>{(g.key==="Enter"||g.key===" ")&&l()},title:r(f?"chat.fileDownloading":d?"chat.fileDownloaded":"chat.clickToDownload"),children:[h.jsx(ei,{size:20,style:{color:u,flexShrink:0}}),h.jsxs("span",{style:{minWidth:0,overflow:"hidden"},children:[h.jsx("span",{style:{display:"block",fontSize:"0.85rem",fontWeight:500,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"var(--color-text-primary)"},children:p}),h.jsx("span",{style:{display:"block",fontSize:"0.75rem",color:"var(--color-text-muted)",marginTop:"2px"},children:Tx(c)})]}),h.jsx("span",{style:{flexShrink:0,fontSize:"0.75rem",color:d?"var(--color-success)":"var(--color-text-muted)"},children:f?`${Math.round(i.progress*100)}%`:d?"✓":"↓"})]})},Kt=({content:e,onFileDownload:t,onGetFileInfo:n})=>{const{isDark:r}=Zo(),i=r?Fb:Mb,o=N.useMemo(()=>({code({className:a,children:l,...s}){const u=/language-(\w+)/.exec(a||""),p=String(l).replace(/\n$/,""),c=p.includes(`
-`);return a?.startsWith("language-")||c?h.jsxs("div",{className:"code-block-wrapper",children:[h.jsx(Sx,{code:p}),h.jsx($e,{language:u?.[1]||"text",style:i,showLineNumbers:!0,customStyle:{margin:0,borderRadius:"8px",fontSize:"0.8rem",lineHeight:"1.5"},codeTagProps:{style:{fontFamily:"var(--font-family-mono)"}},lineNumberStyle:{color:"var(--color-text-muted)",paddingRight:"1em",textAlign:"right",userSelect:"none",minWidth:"2.5em"},children:p})]}):h.jsx("code",{className:"inline-code",...s,children:l})},a({href:a,children:l}){const s=typeof a=="string"&&a.startsWith(vn);if(s&&n&&t){const u=wn(a);return h.jsx(Ho,{path:u,onGetFileInfo:n,onDownload:t})}if(s&&t){const u=wn(a);return h.jsx("button",{className:"file-link",onClick:p=>{p.preventDefault(),p.stopPropagation(),t(u)},type:"button",style:{cursor:"pointer",color:"var(--color-accent-500)",textDecoration:"underline",background:"none",border:"none",font:"inherit",padding:0},children:l})}if(n&&t){const u=typeof a=="string"?Cx(a):null;if(u)return h.jsx(Ho,{path:u,onGetFileInfo:n,onDownload:t})}return typeof a=="string"&&(a.startsWith("http://")||a.startsWith("https://"))?h.jsx("a",{href:a,target:"_blank",rel:"noopener noreferrer",style:{color:"var(--color-accent-500)",textDecoration:"underline"},children:l}):h.jsx("span",{style:{textDecoration:"underline",opacity:.7},children:l})},table({children:a}){return h.jsx("div",{className:"table-wrapper",children:h.jsx("table",{children:a})})},blockquote({children:a}){return h.jsx("blockquote",{className:"custom-blockquote",children:a})}}),[i,r,t,n]);return h.jsx(uf,{remarkPlugins:[Sg],components:o,urlTransform:a=>a.startsWith("computer://")||/^(https?|mailto|tel|file):/i.test(a)||a.startsWith("#")||a.startsWith("/")||!a.includes(":")?a:"",children:e})},xi=({thinking:e,streaming:t,isLastItem:n=!1})=>{const{t:r}=Ye(),[i,o]=N.useState(!!t),a=N.useRef(!1),l=N.useRef(null),[s,u]=N.useState({atTop:!0,atBottom:!0}),p=Cs(e,!!t);N.useEffect(()=>{a.current||(t?o(!0):n||o(!1))},[t,n]),N.useEffect(()=>{if(!t||!i)return;const k=l.current;if(!k)return;k.scrollHeight-k.scrollTop-k.clientHeight<80&&(k.scrollTop=k.scrollHeight)},[p,t,i]);const c=N.useCallback(()=>{const k=l.current;k&&u({atTop:k.scrollTop<4,atBottom:k.scrollHeight-k.scrollTop-k.clientHeight<4})},[]),f=N.useCallback(()=>{a.current=!0,o(k=>!k)},[]);if(!e&&!t)return null;const d=e.length,g=t&&d===0?r("chat.thinking"):r("chat.thoughtCharacters",{count:d});return h.jsxs("div",{className:`chat-thinking ${t?"chat-thinking--streaming":""}`,children:[h.jsxs("button",{className:"chat-thinking__toggle",onClick:f,children:[h.jsx("span",{className:`chat-thinking__chevron ${i?"is-open":""}`,children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M6 4L10 8L6 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsx("span",{className:"chat-thinking__label",children:g})]}),h.jsx("div",{className:`chat-thinking__expand-container ${i?"is-expanded":""}`,children:h.jsx("div",{className:"chat-thinking__expand-inner",children:e&&h.jsx("div",{className:`chat-thinking__content-wrapper ${s.atTop?"at-top":""} ${s.atBottom?"at-bottom":""}`,ref:l,onScroll:c,children:h.jsx("div",{className:"chat-thinking__content",children:h.jsx(Kt,{content:t?p:e})})})})})]})},Sn={explore:"shared.tools.explore",read_file:"shared.tools.read",write_file:"shared.tools.write",list_directory:"tools.ls",bash:"shared.tools.shell",glob:"tools.glob",grep:"tools.grep",create_file:"shared.tools.write",delete_file:"tools.delete",Task:"tools.task",search:"shared.tools.search",edit_file:"shared.tools.edit",web_search:"tools.web",TodoWrite:"shared.tools.todo"},Ax=({tool:e})=>{const{t}=Ye(),[n,r]=N.useState(!1),i=N.useMemo(()=>{const u=e.tool_input;if(!u)return[];const p=u.todos||u.result?.todos;return Array.isArray(p)?p:[]},[e.tool_input]);if(i.length===0)return null;const o=i.filter(u=>u.status==="completed").length,a=o===i.length,l=i.find(u=>u.status==="in_progress"),s=u=>{switch(u){case"completed":return h.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"var(--color-success)",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("path",{d:"M22 11.08V12a10 10 0 1 1-5.93-9.14"}),h.jsx("path",{d:"m9 11 3 3L22 4"})]});case"in_progress":return h.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"var(--color-accent-500)",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("circle",{cx:"12",cy:"12",r:"10"}),h.jsx("polygon",{points:"10 8 16 12 10 16 10 8",fill:"var(--color-accent-500)"})]});case"cancelled":return h.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"var(--color-error)",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("circle",{cx:"12",cy:"12",r:"10"}),h.jsx("path",{d:"m15 9-6 6"}),h.jsx("path",{d:"m9 9 6 6"})]});default:return h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"var(--color-text-muted)",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("circle",{cx:"12",cy:"12",r:"10"})})}};return h.jsxs("div",{className:"chat-todo-card",children:[h.jsxs("div",{className:"chat-todo-card__header",onClick:()=>r(!n),children:[h.jsx("span",{className:"chat-todo-card__icon",children:h.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("rect",{x:"3",y:"5",width:"6",height:"6",rx:"1"}),h.jsx("path",{d:"m3 17 2 2 4-4"}),h.jsx("path",{d:"M13 6h8"}),h.jsx("path",{d:"M13 12h8"}),h.jsx("path",{d:"M13 18h8"})]})}),a&&!n?h.jsx("span",{className:"chat-todo-card__current chat-todo-card__current--done",children:t("chat.allTasksCompleted")}):l&&!n?h.jsx("span",{className:"chat-todo-card__current",children:l.content}):null,h.jsxs("span",{className:"chat-todo-card__right",children:[h.jsx("span",{className:"chat-todo-card__dots",children:i.map((u,p)=>h.jsx("span",{className:`chat-todo-card__dot chat-todo-card__dot--${u.status}`},u.id||p))}),h.jsxs("span",{className:"chat-todo-card__stats",children:[o,"/",i.length]})]}),h.jsx("span",{className:`chat-todo-card__chevron ${n?"is-expanded":""}`,children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("path",{d:"m6 9 6 6 6-6"})})})]}),n&&h.jsx("div",{className:"chat-todo-card__list",children:i.map((u,p)=>h.jsxs("div",{className:`chat-todo-card__item chat-todo-card__item--${u.status}`,children:[s(u.status),h.jsx("span",{className:"chat-todo-card__item-text",children:u.content})]},u.id||p))})]})};function Lx(e){const t=e.tool_input??(()=>{try{return JSON.parse(e.input_preview||"")}catch{return null}})();return t?{description:t.description,agentType:t.subagent_type}:null}function Nx(e,t){if(e.type==="thinking"){const n=(e.content||"").length;return t("chat.thoughtCharacters",{count:n})}if(e.type==="tool"&&e.tool){const n=e.tool,r=n.input_preview?`: ${n.input_preview}`:"";return`${n.name}${r}`}if(e.type==="text"){const n=(e.content||"").length;return t("chat.textCharacters",{count:n})}return""}const _s=({tool:e,now:t,subItems:n=[],onCancelTool:r})=>{const{t:i,language:o}=Ye(),a=N.useRef(null),l=N.useRef(0),[s,u]=N.useState(!1),p=e.status==="running",c=e.status==="completed",f=e.status==="failed"||e.status==="error",d=p&&!!r,g=Lx(e),k=c&&e.duration_ms!=null?Wt(e.duration_ms):p&&e.start_ms?Wt(t-e.start_ms):"",S=p?"running":c?"done":f?"error":"pending",x=n.filter(_=>_.type==="tool"&&_.tool),v=x.filter(_=>_.tool.status==="completed").length,y=x.filter(_=>_.tool.status==="running").length;return N.useEffect(()=>{s&&n.length>l.current&&a.current&&(a.current.scrollTop=a.current.scrollHeight),l.current=n.length},[n.length,s]),h.jsxs("div",{className:`chat-task-card chat-task-card--${S}`,children:[h.jsxs("div",{className:"chat-task-card__header",children:[h.jsx("span",{className:"chat-tool-card__icon",children:p?h.jsx("span",{className:"chat-tool-card__spinner"}):c?h.jsx("span",{className:"chat-tool-card__check",children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M3 8.5L6.5 12L13 4",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}):f?h.jsx("span",{className:"chat-tool-card__error-icon",children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M4 4L12 12M12 4L4 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})})}):h.jsx("span",{className:"chat-tool-card__spinner"})}),h.jsx("span",{className:"chat-tool-card__name",children:g?.description||i("chat.task")}),g?.agentType&&h.jsx("span",{className:"chat-tool-card__type",children:g.agentType}),k&&h.jsx("span",{className:"chat-tool-card__duration",children:k}),d&&h.jsx("button",{className:"chat-tool-card__cancel",onClick:_=>{_.stopPropagation(),r?.(e.id)},"aria-label":i("common.cancel"),children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("rect",{x:"3",y:"3",width:"10",height:"10",rx:"2",fill:"currentColor"})})})]}),n.length>0&&h.jsxs(h.Fragment,{children:[h.jsxs("div",{className:"chat-task-card__summary",onClick:()=>u(_=>!_),children:[h.jsx("span",{className:"chat-task-card__stat",children:i("chat.toolCalls",{count:x.length,suffix:Hi(o,x.length)})}),h.jsxs("span",{className:"chat-task-card__stat-right",children:[h.jsx("span",{className:"chat-task-card__stat--done",children:i("chat.done",{count:v})}),y>0&&h.jsx("span",{className:"chat-task-card__stat--running",children:i("chat.running",{count:y})})]}),h.jsx("span",{className:`chat-task-card__chevron ${s?"is-expanded":""}`,children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("path",{d:"m6 9 6 6 6-6"})})})]}),s&&h.jsx("div",{className:"chat-task-card__steps",ref:a,children:n.map((_,C)=>{if(_.type==="thinking")return h.jsxs("div",{className:"chat-task-card__step chat-task-card__step--thinking",children:[h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("path",{d:"m6 9 6 6 6-6"})}),h.jsx("span",{children:Nx(_,i)})]},`sub-think-${C}`);if(_.type==="tool"&&_.tool){const m=_.tool,T=m.status==="completed",j=m.status==="failed"||m.status==="error";return h.jsxs("div",{className:`chat-task-card__step chat-task-card__step--tool ${T?"is-done":j?"is-error":"is-running"}`,children:[T?h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M3 8.5L6.5 12L13 4",stroke:"var(--color-success)",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}):j?h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M4 4L12 12M12 4L4 12",stroke:"var(--color-error)",strokeWidth:"2",strokeLinecap:"round"})}):h.jsx("span",{className:"chat-task-card__step-spinner"}),h.jsx("span",{className:"chat-task-card__step-name",children:m.name}),(()=>{const A=Es(m);return A?h.jsx("span",{className:"chat-task-card__step-preview",children:A}):null})(),T&&m.duration_ms!=null&&h.jsx("span",{className:"chat-task-card__step-duration",children:Wt(m.duration_ms)})]},`sub-tool-${m.id}-${C}`)}return null})})]})]})};function Es(e){if(!e.input_preview)return null;try{const t=JSON.parse(e.input_preview);if(!t||typeof t!="object")return null;const n=o=>{const a=o.replace(/\\/g,"/").split("/");return a[a.length-1]||o};let r=null;const i=t.file_path||t.path;switch(e.name){case"Read":case"Write":case"Edit":case"LS":case"StrReplace":case"delete_file":r=i?n(i):null;break;case"Glob":case"Grep":r=t.pattern||null;break;case"Bash":case"Shell":r=t.description||t.command||null;break;case"web_search":case"WebSearch":r=t.search_term||t.query||null;break;case"WebFetch":r=t.url||null;break;case"SemanticSearch":r=t.query||null;break;default:r=Object.values(t).find(a=>typeof a=="string"&&a.length>0&&a.length<80)||null}return r?r.length>60?r.slice(0,60)+"…":r:null}catch{return null}}const Wo=({tool:e,now:t,onCancelTool:n})=>{const{t:r}=Ye(),i=e.name.toLowerCase().replace(/[\s-]/g,"_"),o=Sn[i]||Sn[e.name],a=o?r(o):"Tool",l=e.status==="running",s=e.status==="completed",u=e.status==="failed"||e.status==="error",p=l&&!!n,c=Es(e),f=s&&e.duration_ms!=null?Wt(e.duration_ms):l&&e.start_ms?Wt(t-e.start_ms):"",d=l?"running":s?"done":u?"error":"pending";return h.jsx("div",{className:`chat-tool-card chat-tool-card--${d}`,children:h.jsxs("div",{className:"chat-tool-card__row",children:[h.jsx("span",{className:"chat-tool-card__icon",children:l?h.jsx("span",{className:"chat-tool-card__spinner"}):s?h.jsx("span",{className:"chat-tool-card__check",children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M3 8.5L6.5 12L13 4",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}):u?h.jsx("span",{className:"chat-tool-card__error-icon",children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M4 4L12 12M12 4L4 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})})}):h.jsx("span",{className:"chat-tool-card__spinner"})}),h.jsxs("span",{className:"chat-tool-card__name",children:[e.name,c&&h.jsxs("span",{className:"chat-tool-card__preview",children:[" ",c]})]}),h.jsx("span",{className:"chat-tool-card__type",children:a}),f&&h.jsx("span",{className:"chat-tool-card__duration",children:f}),p&&h.jsx("button",{className:"chat-tool-card__cancel",onClick:g=>{g.stopPropagation(),n?.(e.id)},"aria-label":r("common.cancel"),children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("rect",{x:"3",y:"3",width:"10",height:"10",rx:"2",fill:"currentColor"})})})]})})},Ix=new Set(["Read","Grep","Glob","SemanticSearch"]);function jx(e,t){const n=new Map,r=[];for(const i of e){const o=i.name.toLowerCase().replace(/[\s-]/g,"_"),a=Sn[o]||Sn[i.name],l=a?t(a):i.name,s=l.toLowerCase(),u=n.get(s);if(u){u.count+=1;continue}n.set(s,{label:l,count:1}),r.push(s)}return r.map(i=>{const o=n.get(i);return`${o.label} ${o.count}`}).join(", ")}const Rx=({tools:e})=>{const{t}=Ye(),[n,r]=N.useState(!1);if(e.length===0)return null;const i=e.filter(s=>s.status==="completed").length,o=i===e.length,a=jx(e,t),l=o?t("chat.readToolsDone",{summary:a}):t("chat.readToolsRunning",{summary:a,doneCount:i});return h.jsxs("div",{className:`chat-thinking ${o?"":"chat-thinking--streaming"}`,children:[h.jsxs("button",{className:"chat-thinking__toggle",onClick:()=>r(s=>!s),children:[h.jsx("span",{className:`chat-thinking__chevron ${n?"is-open":""}`,children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M6 4L10 8L6 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsx("span",{className:"chat-thinking__label",children:l})]}),n&&h.jsx("div",{className:"chat-thinking__content-wrapper at-top at-bottom",children:h.jsx("div",{className:"chat-thinking__content",children:e.map(s=>{const u=s.input_preview||"";return h.jsxs("div",{style:{fontSize:"12px",padding:"2px 0",opacity:.8},children:[s.status==="completed"?"✓":"⋯"," ",s.name," ",u]},s.id)})})})]})},Ox=2,ki=({tools:e,now:t,onCancelTool:n})=>{const{t:r,language:i}=Ye(),o=N.useRef(null),a=N.useRef(0),[l,s]=N.useState(!1);if(N.useEffect(()=>{l&&e.length>a.current&&o.current&&(o.current.scrollTop=o.current.scrollHeight),a.current=e.length},[e.length,l]),!e||e.length===0)return null;if(e.length<=Ox)return h.jsx("div",{className:"chat-tool-list",children:e.map(c=>h.jsx(Wo,{tool:c,now:t,onCancelTool:n},c.id))});const u=e.filter(c=>c.status==="running").length,p=e.filter(c=>c.status==="completed").length;return h.jsxs("div",{className:"chat-tool-list chat-tool-list--collapsed",children:[h.jsxs("div",{className:"chat-tool-list__header",onClick:()=>s(c=>!c),children:[h.jsx("span",{className:"chat-tool-list__count",children:r("chat.toolCalls",{count:e.length,suffix:Hi(i,e.length)})}),h.jsxs("span",{className:"chat-tool-list__stats",children:[p>0&&h.jsx("span",{className:"chat-tool-list__stat chat-tool-list__stat--done",children:r("chat.done",{count:p})}),u>0&&h.jsx("span",{className:"chat-tool-list__stat chat-tool-list__stat--running",children:r("chat.running",{count:u})})]}),h.jsx("span",{className:`chat-tool-list__chevron ${l?"is-expanded":""}`,children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("path",{d:"m6 9 6 6 6-6"})})})]}),l&&h.jsx("div",{className:"chat-tool-list__scroll",ref:o,children:e.map(c=>h.jsx(Wo,{tool:c,now:t,onCancelTool:n},c.id))})]})},ti=()=>h.jsxs("span",{className:"chat-msg__typing",children:[h.jsx("span",{}),h.jsx("span",{}),h.jsx("span",{})]});function Cs(e,t){const[n,r]=N.useState(t?"":e),i=N.useRef(t?0:e.length),o=N.useRef(e),a=N.useRef(null),l=N.useRef(3);return N.useEffect(()=>{if(!t){a.current&&(clearInterval(a.current),a.current=null),i.current=e.length,o.current=e,r(e);return}o.current=e,e.length0){const c=26.666666666666668;l.current=Math.max(Math.ceil(s/c),2),a.current||(a.current=setInterval(()=>{const f=o.current,d=i.current;if(d>=f.length){a.current&&(clearInterval(a.current),a.current=null);return}const g=Math.min(d+l.current,f.length);i.current=g,r(f.slice(0,g))},30))}},[e,t]),N.useEffect(()=>()=>{a.current&&clearInterval(a.current)},[]),n}const Ts=({content:e,onFileDownload:t,onGetFileInfo:n})=>{const r=Cs(e,!0);return h.jsx(Kt,{content:r,onFileDownload:t,onGetFileInfo:n})},_n=e=>!e||e.name!=="AskUserQuestion"||!e.tool_input?!1:!["completed","failed","cancelled","rejected"].includes(e.status);function Dx(e,t){const n=t.split(".");let r=e;for(const i of n){if(!r||typeof r!="object"||!(i in r))return null;r=r[i]}return typeof r=="string"?r:null}const Mx=new Set(["other",...Object.values(Ys).map(e=>Dx(e,"common.other")).filter(e=>!!e).map(e=>e.trim().toLowerCase())]),xt=e=>{const t=(e||"").trim().toLowerCase();return Mx.has(t)},As=({tool:e,onAnswer:t})=>{const{t:n,language:r}=Ye(),i=e.tool_input?.questions||[],[o,a]=N.useState({}),[l,s]=N.useState({}),[u,p]=N.useState(!1),[c,f]=N.useState(!1),d=N.useMemo(()=>i.map(x=>{const v=Array.isArray(x.options)?x.options:[],y=v.some(_=>xt(_?.label));return{...x,options:v,hasBuiltInOther:y}}),[i]);if(d.length===0)return null;const g=(x,v,y)=>{a(_=>{if(y){const C=_[x]||[];return{..._,[x]:C.includes(v)?C.filter(m=>m!==v):[...C,v]}}return{..._,[x]:_[x]===v?void 0:v}})},k=async()=>{if(!S||u||c)return;const x={};d.forEach((v,y)=>{const _=o[y],C=(l[y]||"").trim();Array.isArray(_)?x[String(y)]=_.map(m=>xt(m)&&C||m):xt(_)?x[String(y)]=C||_:x[String(y)]=_??""}),p(!0);try{await t(e.id,x),f(!0)}finally{p(!1)}},S=d.every((x,v)=>{const y=o[v];return(x.multiSelect?Array.isArray(y)&&y.length>0:!!y)?!(Array.isArray(y)?y.some(m=>xt(m)):xt(y))||!!(l[v]||"").trim():!1});return h.jsxs("div",{className:"chat-ask-card",children:[h.jsxs("div",{className:"chat-ask-card__header",children:[h.jsx("span",{className:"chat-ask-card__count",children:n("chat.askQuestionCount",{count:i.length,suffix:Hi(r,i.length)})}),!c&&!u&&h.jsx("span",{className:"chat-ask-card__waiting",children:n("chat.waiting")})]}),d.map((x,v)=>{const y=o[v],_=Array.isArray(y)?y.some(C=>xt(C)):xt(y);return h.jsxs("div",{className:"chat-ask-card__question",children:[h.jsxs("div",{className:"chat-ask-card__question-header",children:[h.jsx("span",{className:"chat-ask-card__tag",children:x.header}),h.jsx("span",{className:"chat-ask-card__question-text",children:x.question})]}),h.jsxs("div",{className:"chat-ask-card__options",children:[(x.options||[]).map((C,m)=>{const T=x.multiSelect?(o[v]||[]).includes(C.label):o[v]===C.label;return h.jsxs("button",{className:`chat-ask-card__option ${T?"is-selected":""}`,onClick:()=>g(v,C.label,x.multiSelect),disabled:c||u,children:[h.jsx("span",{className:`chat-ask-card__radio ${x.multiSelect?"chat-ask-card__radio--multi":""}`,children:T&&h.jsx("svg",{width:"8",height:"8",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M3 8L6.5 11.5L13 4.5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsx("span",{className:"chat-ask-card__option-label",children:C.label}),C.description&&h.jsx("span",{className:"chat-ask-card__option-desc",children:C.description})]},m)}),!x.hasBuiltInOther&&h.jsxs("button",{className:`chat-ask-card__option ${_?"is-selected":""}`,onClick:()=>g(v,"Other",x.multiSelect),disabled:c||u,children:[h.jsx("span",{className:`chat-ask-card__radio ${x.multiSelect?"chat-ask-card__radio--multi":""}`,children:_&&h.jsx("svg",{width:"8",height:"8",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M3 8L6.5 11.5L13 4.5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsx("span",{className:"chat-ask-card__option-label",children:n("common.other")}),h.jsx("span",{className:"chat-ask-card__option-desc",children:n("common.customTextInput")})]}),_&&h.jsx("input",{className:"chat-ask-card__custom-input",placeholder:n("common.typeYourAnswer"),value:l[v]||"",onChange:C=>s(m=>({...m,[v]:C.target.value})),disabled:c||u})]})]},v)}),h.jsxs("button",{className:"chat-ask-card__submit chat-ask-card__submit--bottom",disabled:!S||c||u,onClick:k,children:[h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M2 8L6 12L14 4",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}),n(c?"common.submitted":u?"common.submitting":"common.submit")]})]})};function Ls(e){const t=[];let n=null;for(const r of e){if(r.type==="tool"&&r.tool?.name==="Task"){const i={...r,subItems:[]};t.push(i),n=i;continue}if(r.is_subagent&&n){n.subItems.push(r);continue}r.is_subagent||t.push(r)}return t}function Nt(e){const t=[];for(const n of e){const r=t[t.length-1];r&&r.type===n.type?r.entries.push(n):t.push({type:n.type,entries:[n]})}return t}function Ns(e,t,n){return n?e.map((r,i)=>h.jsx(As,{tool:r.tool,onAnswer:n},`${t}-ask-${r.tool.id}-${i}`)):null}function It(e,t,n,r,i,o,a,l){return e.map((s,u)=>{if(s.type==="thinking"){const p=s.entries.map(f=>f.content||"").join(`
+|(?![\\s\\S])))+`,"m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(i)[0]}}}}),Object.defineProperty(n.languages.diff,"PREFIXES",{value:r})})(t)}return zr}var Pr,Lo;function _y(){if(Lo)return Pr;Lo=1,Pr=e,e.displayName="markupTemplating",e.aliases=[];function e(t){(function(n){function r(i,o){return"___"+i.toUpperCase()+o+"___"}Object.defineProperties(n.languages["markup-templating"]={},{buildPlaceholders:{value:function(i,o,a,l){if(i.language===o){var s=i.tokenStack=[];i.code=i.code.replace(a,function(u){if(typeof l=="function"&&!l(u))return u;for(var p=s.length,c;i.code.indexOf(c=r(o,p))!==-1;)++p;return s[p]=u,c}),i.grammar=n.languages.markup}}},tokenizePlaceholders:{value:function(i,o){if(i.language!==o||!i.tokenStack)return;i.grammar=n.languages[o];var a=0,l=Object.keys(i.tokenStack);function s(u){for(var p=0;p=l.length);p++){var c=u[p];if(typeof c=="string"||c.content&&typeof c.content=="string"){var f=l[a],d=i.tokenStack[f],g=typeof c=="string"?c:c.content,k=r(o,f),S=g.indexOf(k);if(S>-1){++a;var x=g.substring(0,S),v=new n.Token(o,n.tokenize(d,i.grammar),"language-"+o,d),b=g.substring(S+k.length),_=[];x&&_.push.apply(_,s([x])),_.push(v),b&&_.push.apply(_,s([b])),typeof c=="string"?u.splice.apply(u,[p,1].concat(_)):c.content=_}}else c.content&&s(c.content)}return u}s(i.tokens)}}})})(t)}return Pr}var Br,No;function Ey(){if(No)return Br;No=1,Br=e,e.displayName="go",e.aliases=[];function e(t){t.languages.go=t.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),t.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete t.languages.go["class-name"]}return Br}var $r,Io;function Cy(){if(Io)return $r;Io=1,$r=e,e.displayName="java",e.aliases=[];function e(t){(function(n){var r=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,i=/(^|[^\w.])(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,o={pattern:RegExp(i+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};n.languages.java=n.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[o,{pattern:RegExp(i+/[A-Z]\w*(?=\s+\w+\s*[;,=()])/.source),lookbehind:!0,inside:o.inside}],keyword:r,function:[n.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),n.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),n.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":o,keyword:r,punctuation:/[<>(),.:]/,operator:/[?&|]/}},namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(//g,function(){return r.source})),lookbehind:!0,inside:{punctuation:/\./}}})})(t)}return $r}var qr,jo;function fs(){if(jo)return qr;jo=1,qr=e,e.displayName="typescript",e.aliases=["ts"];function e(t){(function(n){n.languages.typescript=n.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),n.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete n.languages.typescript.parameter,delete n.languages.typescript["literal-property"];var r=n.languages.extend("typescript",{});delete r["class-name"],n.languages.typescript["class-name"].inside=r,n.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:r}}}}),n.languages.ts=n.languages.typescript})(t)}return qr}var Ur,Ro;function Ty(){if(Ro)return Ur;Ro=1,Ur=e,e.displayName="json",e.aliases=["webmanifest"];function e(t){t.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},t.languages.webmanifest=t.languages.json}return Ur}var Hr,Oo;function hs(){if(Oo)return Hr;Oo=1,Hr=e,e.displayName="jsx",e.aliases=[];function e(t){(function(n){var r=n.util.clone(n.languages.javascript),i=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,o=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,a=/(?:\{*\.{3}(?:[^{}]|)*\})/.source;function l(p,c){return p=p.replace(//g,function(){return i}).replace(//g,function(){return o}).replace(//g,function(){return a}),RegExp(p,c)}a=l(a).source,n.languages.jsx=n.languages.extend("markup",r),n.languages.jsx.tag.pattern=l(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),n.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,n.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,n.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,n.languages.jsx.tag.inside.comment=r.comment,n.languages.insertBefore("inside","attr-name",{spread:{pattern:l(//.source),inside:n.languages.jsx}},n.languages.jsx.tag),n.languages.insertBefore("inside","special-attr",{script:{pattern:l(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:n.languages.jsx}}},n.languages.jsx.tag);var s=function(p){return p?typeof p=="string"?p:typeof p.content=="string"?p.content:p.content.map(s).join(""):""},u=function(p){for(var c=[],f=0;f0&&c[c.length-1].tagName===s(d.content[0].content[1])&&c.pop():d.content[d.content.length-1].content==="/>"||c.push({tagName:s(d.content[0].content[1]),openedBraces:0}):c.length>0&&d.type==="punctuation"&&d.content==="{"?c[c.length-1].openedBraces++:c.length>0&&c[c.length-1].openedBraces>0&&d.type==="punctuation"&&d.content==="}"?c[c.length-1].openedBraces--:g=!0),(g||typeof d=="string")&&c.length>0&&c[c.length-1].openedBraces===0){var k=s(d);f0&&(typeof p[f-1]=="string"||p[f-1].type==="plain-text")&&(k=s(p[f-1])+k,p.splice(f-1,1),f--),p[f]=new n.Token("plain-text",k,null,k)}d.content&&typeof d.content!="string"&&u(d.content)}};n.hooks.add("after-tokenize",function(p){p.language!=="jsx"&&p.language!=="tsx"||u(p.tokens)})})(t)}return Hr}var Wr,Do;function Ay(){if(Do)return Wr;Do=1,Wr=e,e.displayName="kotlin",e.aliases=["kt","kts"];function e(t){(function(n){n.languages.kotlin=n.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete n.languages.kotlin["class-name"];var r={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:n.languages.kotlin}};n.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:r},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:r},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete n.languages.kotlin.string,n.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),n.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),n.languages.kt=n.languages.kotlin,n.languages.kts=n.languages.kotlin})(t)}return Wr}var Vr,Mo;function Ly(){if(Mo)return Vr;Mo=1;var e=_y();Vr=t,t.displayName="php",t.aliases=[];function t(n){n.register(e),(function(r){var i=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,o=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],a=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,l=/=>|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,s=/[{}\[\](),:;]/;r.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:i,variable:/\$+(?:\w+\b|(?=\{))/,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},"function-definition":{pattern:/(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,lookbehind:!0,alias:"function"},keyword:[{pattern:/(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string|void)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(\byield\s+)from\b/i,lookbehind:!0},/\bclass\b/i,{pattern:/((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|new|or|parent|print|private|protected|public|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i,lookbehind:!0}],"argument-name":{pattern:/([(,]\s+)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:o,function:{pattern:/(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,lookbehind:!0,inside:{punctuation:/\\/}},property:{pattern:/(->\s*)\w+/,lookbehind:!0},number:a,operator:l,punctuation:s};var u={pattern:/\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,lookbehind:!0,inside:r.languages.php},p=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:u}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:u}}];r.languages.insertBefore("php","variable",{string:p,attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=\]$)/,lookbehind:!0,inside:{comment:i,string:p,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:o,number:a,operator:l,punctuation:s}},delimiter:{pattern:/^#\[|\]$/,alias:"punctuation"}}}}),r.hooks.add("before-tokenize",function(c){if(/<\?/.test(c.code)){var f=/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g;r.languages["markup-templating"].buildPlaceholders(c,"php",f)}}),r.hooks.add("after-tokenize",function(c){r.languages["markup-templating"].tokenizePlaceholders(c,"php")})})(n)}return Vr}var Gr,Fo;function Ny(){if(Fo)return Gr;Fo=1,Gr=e,e.displayName="markdown",e.aliases=["md"];function e(t){(function(n){var r=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function i(f){return f=f.replace(//g,function(){return r}),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+f+")")}var o=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,function(){return o}),l=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;n.languages.markdown=n.languages.extend("markup",{}),n.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:n.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+l+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+l+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(o),inside:n.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+l+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(o),alias:"important",inside:n.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:i(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:i(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:i(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:i(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach(function(f){["url","bold","italic","strike","code-snippet"].forEach(function(d){f!==d&&(n.languages.markdown[f].inside.content.inside[d]=n.languages.markdown[d])})}),n.hooks.add("after-tokenize",function(f){if(f.language!=="markdown"&&f.language!=="md")return;function d(g){if(!(!g||typeof g=="string"))for(var k=0,S=g.length;k",quot:'"'},p=String.fromCodePoint||String.fromCharCode;function c(f){var d=f.replace(s,"");return d=d.replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,function(g,k){if(k=k.toLowerCase(),k[0]==="#"){var S;return k[1]==="x"?S=parseInt(k.slice(2),16):S=Number(k.slice(1)),p(S)}else{var x=u[k];return x||g}}),d}n.languages.md=n.languages.markdown})(t)}return Gr}var Zr,zo;function Iy(){if(zo)return Zr;zo=1,Zr=e,e.displayName="python",e.aliases=["py"];function e(t){t.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern://,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},t.languages.python["string-interpolation"].inside.interpolation.inside.rest=t.languages.python,t.languages.py=t.languages.python}return Zr}var Xr,Po;function jy(){if(Po)return Xr;Po=1,Xr=e,e.displayName="rust",e.aliases=[];function e(t){(function(n){for(var r=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|)*\*\//.source,i=0;i<2;i++)r=r.replace(//g,function(){return r});r=r.replace(//g,function(){return/[^\s\S]/.source}),n.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+r),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<=?|>>?=?|[@?]/},n.languages.rust["closure-params"].inside.rest=n.languages.rust,n.languages.rust.attribute.inside.string=n.languages.rust.string})(t)}return Xr}var Kr,Bo;function Ry(){if(Bo)return Kr;Bo=1,Kr=e,e.displayName="swift",e.aliases=[];function e(t){t.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+(/(?:elseif|if)\b/.source+"(?:[ ]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+")+"|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},t.languages.swift["string-literal"].forEach(function(n){n.inside.interpolation.inside=t.languages.swift})}return Kr}var Yr,$o;function Oy(){if($o)return Yr;$o=1,Yr=e,e.displayName="yaml",e.aliases=["yml"];function e(t){(function(n){var r=/[*&][^\s[\]{},]+/,i=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,o="(?:"+i.source+"(?:[ ]+"+r.source+")?|"+r.source+"(?:[ ]+"+i.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source}),l=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function s(u,p){p=(p||"").replace(/m/g,"")+"m";var c=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,function(){return o}).replace(/<>/g,function(){return u});return RegExp(c,p)}n.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,function(){return o})),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,function(){return o}).replace(/<>/g,function(){return"(?:"+a+"|"+l+")"})),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:s(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:s(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:s(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:s(l),lookbehind:!0,greedy:!0},number:{pattern:s(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:i,important:r,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},n.languages.yml=n.languages.yaml})(t)}return Yr}var Qr,qo;function Dy(){if(qo)return Qr;qo=1;var e=hs(),t=fs();Qr=n,n.displayName="tsx",n.aliases=[];function n(r){r.register(e),r.register(t),(function(i){var o=i.util.clone(i.languages.typescript);i.languages.tsx=i.languages.extend("jsx",o),delete i.languages.tsx.parameter,delete i.languages.tsx["literal-property"];var a=i.languages.tsx.tag;a.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+a.pattern.source+")",a.pattern.flags),a.lookbehind=!0})(r)}return Qr}const My={'code[class*="language-"]':{color:"#393A34",fontFamily:'"Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace',direction:"ltr",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",fontSize:".9em",lineHeight:"1.2em",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none"},'pre[class*="language-"]':{color:"#393A34",fontFamily:'"Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace',direction:"ltr",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",fontSize:".9em",lineHeight:"1.2em",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none",padding:"1em",margin:".5em 0",overflow:"auto",border:"1px solid #dddddd",backgroundColor:"white"},'pre > code[class*="language-"]':{fontSize:"1em"},'pre[class*="language-"]::-moz-selection':{background:"#C1DEF1"},'pre[class*="language-"] ::-moz-selection':{background:"#C1DEF1"},'code[class*="language-"]::-moz-selection':{background:"#C1DEF1"},'code[class*="language-"] ::-moz-selection':{background:"#C1DEF1"},'pre[class*="language-"]::selection':{background:"#C1DEF1"},'pre[class*="language-"] ::selection':{background:"#C1DEF1"},'code[class*="language-"]::selection':{background:"#C1DEF1"},'code[class*="language-"] ::selection':{background:"#C1DEF1"},':not(pre) > code[class*="language-"]':{padding:".2em",paddingTop:"1px",paddingBottom:"1px",background:"#f8f8f8",border:"1px solid #dddddd"},comment:{color:"#008000",fontStyle:"italic"},prolog:{color:"#008000",fontStyle:"italic"},doctype:{color:"#008000",fontStyle:"italic"},cdata:{color:"#008000",fontStyle:"italic"},namespace:{Opacity:".7"},string:{color:"#A31515"},punctuation:{color:"#393A34"},operator:{color:"#393A34"},url:{color:"#36acaa"},symbol:{color:"#36acaa"},number:{color:"#36acaa"},boolean:{color:"#36acaa"},variable:{color:"#36acaa"},constant:{color:"#36acaa"},inserted:{color:"#36acaa"},atrule:{color:"#0000ff"},keyword:{color:"#0000ff"},"attr-value":{color:"#0000ff"},".language-autohotkey .token.selector":{color:"#0000ff"},".language-json .token.boolean":{color:"#0000ff"},".language-json .token.number":{color:"#0000ff"},'code[class*="language-css"]':{color:"#0000ff"},function:{color:"#393A34"},deleted:{color:"#9a050f"},".language-autohotkey .token.tag":{color:"#9a050f"},selector:{color:"#800000"},".language-autohotkey .token.keyword":{color:"#00009f"},important:{color:"#e90",fontWeight:"bold"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"},"class-name":{color:"#2B91AF"},".language-json .token.property":{color:"#2B91AF"},tag:{color:"#800000"},"attr-name":{color:"#ff0000"},property:{color:"#ff0000"},regex:{color:"#ff0000"},entity:{color:"#ff0000"},"directive.tag.tag":{background:"#ffff00",color:"#393A34"},".line-numbers.line-numbers .line-numbers-rows":{borderRightColor:"#a5a5a5"},".line-numbers .line-numbers-rows > span:before":{color:"#2B91AF"},".line-highlight.line-highlight":{background:"linear-gradient(to right, rgba(193, 222, 241, 0.2) 70%, rgba(221, 222, 241, 0))"}},Fy={'pre[class*="language-"]':{color:"#d4d4d4",fontSize:"13px",textShadow:"none",fontFamily:'Menlo, Monaco, Consolas, "Andale Mono", "Ubuntu Mono", "Courier New", monospace',direction:"ltr",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",lineHeight:"1.5",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none",padding:"1em",margin:".5em 0",overflow:"auto",background:"#1e1e1e"},'code[class*="language-"]':{color:"#d4d4d4",fontSize:"13px",textShadow:"none",fontFamily:'Menlo, Monaco, Consolas, "Andale Mono", "Ubuntu Mono", "Courier New", monospace',direction:"ltr",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",lineHeight:"1.5",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none"},'pre[class*="language-"]::selection':{textShadow:"none",background:"#264F78"},'code[class*="language-"]::selection':{textShadow:"none",background:"#264F78"},'pre[class*="language-"] *::selection':{textShadow:"none",background:"#264F78"},'code[class*="language-"] *::selection':{textShadow:"none",background:"#264F78"},':not(pre) > code[class*="language-"]':{padding:".1em .3em",borderRadius:".3em",color:"#db4c69",background:"#1e1e1e"},".namespace":{Opacity:".7"},"doctype.doctype-tag":{color:"#569CD6"},"doctype.name":{color:"#9cdcfe"},comment:{color:"#6a9955"},prolog:{color:"#6a9955"},punctuation:{color:"#d4d4d4"},".language-html .language-css .token.punctuation":{color:"#d4d4d4"},".language-html .language-javascript .token.punctuation":{color:"#d4d4d4"},property:{color:"#9cdcfe"},tag:{color:"#569cd6"},boolean:{color:"#569cd6"},number:{color:"#b5cea8"},constant:{color:"#9cdcfe"},symbol:{color:"#b5cea8"},inserted:{color:"#b5cea8"},unit:{color:"#b5cea8"},selector:{color:"#d7ba7d"},"attr-name":{color:"#9cdcfe"},string:{color:"#ce9178"},char:{color:"#ce9178"},builtin:{color:"#ce9178"},deleted:{color:"#ce9178"},".language-css .token.string.url":{textDecoration:"underline"},operator:{color:"#d4d4d4"},entity:{color:"#569cd6"},"operator.arrow":{color:"#569CD6"},atrule:{color:"#ce9178"},"atrule.rule":{color:"#c586c0"},"atrule.url":{color:"#9cdcfe"},"atrule.url.function":{color:"#dcdcaa"},"atrule.url.punctuation":{color:"#d4d4d4"},keyword:{color:"#569CD6"},"keyword.module":{color:"#c586c0"},"keyword.control-flow":{color:"#c586c0"},function:{color:"#dcdcaa"},"function.maybe-class-name":{color:"#dcdcaa"},regex:{color:"#d16969"},important:{color:"#569cd6"},italic:{fontStyle:"italic"},"class-name":{color:"#4ec9b0"},"maybe-class-name":{color:"#4ec9b0"},console:{color:"#9cdcfe"},parameter:{color:"#9cdcfe"},interpolation:{color:"#9cdcfe"},"punctuation.interpolation-punctuation":{color:"#569cd6"},variable:{color:"#9cdcfe"},"imports.maybe-class-name":{color:"#9cdcfe"},"exports.maybe-class-name":{color:"#9cdcfe"},escape:{color:"#d7ba7d"},"tag.punctuation":{color:"#808080"},cdata:{color:"#808080"},"attr-value":{color:"#ce9178"},"attr-value.punctuation":{color:"#ce9178"},"attr-value.punctuation.attr-equals":{color:"#d4d4d4"},namespace:{color:"#4ec9b0"},'pre[class*="language-javascript"]':{color:"#9cdcfe"},'code[class*="language-javascript"]':{color:"#9cdcfe"},'pre[class*="language-jsx"]':{color:"#9cdcfe"},'code[class*="language-jsx"]':{color:"#9cdcfe"},'pre[class*="language-typescript"]':{color:"#9cdcfe"},'code[class*="language-typescript"]':{color:"#9cdcfe"},'pre[class*="language-tsx"]':{color:"#9cdcfe"},'code[class*="language-tsx"]':{color:"#9cdcfe"},'pre[class*="language-css"]':{color:"#ce9178"},'code[class*="language-css"]':{color:"#ce9178"},'pre[class*="language-html"]':{color:"#d4d4d4"},'code[class*="language-html"]':{color:"#d4d4d4"},".language-regex .token.anchor":{color:"#dcdcaa"},".language-html .token.punctuation":{color:"#808080"},'pre[class*="language-"] > code[class*="language-"]':{position:"relative",zIndex:"1"},".line-highlight.line-highlight":{background:"#f7ebc6",boxShadow:"inset 5px 0 0 #f7d87c",zIndex:"0"}};var zy=vy();const gs=me(zy);var Py=ds();const By=me(Py);var $y=xy();const qy=me($y);var Uy=ky();const ms=me(Uy);var Hy=cs();const Wy=me(Hy);var Vy=Sy();const Gy=me(Vy);var Zy=Ey();const Xy=me(Zy);var Ky=Cy();const Yy=me(Ky);var Qy=ps();const bs=me(Qy);var Jy=Ty();const ex=me(Jy);var tx=hs();const nx=me(tx);var rx=Ay();const ix=me(rx);var ax=Ny();const ys=me(ax);var ox=us();const Ui=me(ox);var lx=Ly();const sx=me(lx);var ux=Iy();const xs=me(ux);var cx=wy();const ks=me(cx);var px=jy();const dx=me(px);var fx=yy();const hx=me(fx);var gx=Ry();const mx=me(gx);var bx=Dy();const yx=me(bx);var xx=fs();const vs=me(xx);var kx=Oy();const ws=me(kx);function Je(e,t){Ks(e)||t(e instanceof Error?e.message:String(e))}const vx={bash:gs,c:By,cpp:qy,csharp:ms,css:Wy,diff:Gy,go:Xy,java:Yy,javascript:bs,json:ex,jsx:nx,kotlin:ix,markdown:ys,markup:Ui,php:sx,python:xs,ruby:ks,rust:dx,sql:hx,swift:mx,tsx:yx,typescript:vs,yaml:ws};Object.entries(vx).forEach(([e,t])=>{$e.registerLanguage(e,t)});$e.registerLanguage("cs",ms);$e.registerLanguage("html",Ui);$e.registerLanguage("js",bs);$e.registerLanguage("md",ys);$e.registerLanguage("py",xs);$e.registerLanguage("rb",ks);$e.registerLanguage("sh",gs);$e.registerLanguage("ts",vs);$e.registerLanguage("xml",Ui);$e.registerLanguage("yml",ws);function Wt(e){return e<1e3?`${Math.round(e)}ms`:`${(e/1e3).toFixed(1)}s`}function Hi(e,t){return e==="en-US"&&t!==1?"s":""}function wx(e,t){if(!e||e.length<=t)return e;const n=t-3,r=Math.ceil(n*.6),i=n-r;return e.slice(0,r)+"..."+e.slice(-i)}function Jr(e){return e.replace(/#img:\S+\s*/g,"").replace(/\[Image:.*?\]\n(?:Path:.*?\n|Image ID:.*?\n)?/g,"").trim()}function Ss(e){if(navigator.clipboard?.writeText)return navigator.clipboard.writeText(e);const t=document.createElement("textarea");t.value=e,t.style.cssText="position:fixed;left:-9999px;top:-9999px;opacity:0",document.body.appendChild(t),t.select();try{document.execCommand("copy")}finally{document.body.removeChild(t)}return Promise.resolve()}const Sx=({code:e})=>{const[t,n]=N.useState(!1),r=async()=>{try{await Ss(e),n(!0),setTimeout(()=>n(!1),2e3)}catch{}};return h.jsx("button",{className:`copy-button${t?" copy-success":""}`,onClick:r,type:"button",children:t?h.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("polyline",{points:"20 6 9 17 4 12"})}):h.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),h.jsx("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})})},vn="computer://",bi="file://",Uo="{{workspaceFolder}}",yi="bitfun.mobile.last_selected_model_id",_x=new Set(["js","jsx","ts","tsx","mjs","cjs","mts","cts","py","pyw","pyi","rs","go","java","kt","kts","scala","groovy","c","cpp","cc","cxx","h","hpp","hxx","hh","cs","rb","php","swift","vue","svelte","css","scss","less","sass","json","jsonc","yaml","yml","toml","xml","md","mdx","rst","txt","sh","bash","zsh","fish","ps1","bat","cmd","sql","graphql","gql","proto","lock","env","ini","cfg","conf","cj","ets","editorconfig","gitignore","log"]),Ex=new Set(["pdf","doc","docx","xls","xlsx","ppt","pptx","odt","ods","odp","rtf","pages","numbers","key","png","jpg","jpeg","gif","bmp","svg","webp","ico","tiff","tif","zip","tar","gz","bz2","7z","rar","dmg","iso","xz","mp3","wav","ogg","flac","aac","m4a","wma","mp4","avi","mkv","mov","webm","wmv","flv","csv","tsv","sqlite","db","parquet","epub","mobi","apk","ipa","exe","msi","deb","rpm","ttf","otf","woff","woff2"]);function wn(e){let t=e;e.startsWith(vn)?t=e.slice(vn.length):e.startsWith(bi)?t=e.slice(bi.length):e.startsWith("file:")&&(t=e.slice(5)),t.startsWith(Uo)&&(t=t.slice(Uo.length),t.startsWith("/")&&(t=t.slice(1))),/^\/[A-Za-z]:[\\/]/.test(t)&&(t=t.slice(1));try{return decodeURIComponent(t)}catch{return t}}function Cx(e){if(!e||e==="/")return null;let t;if(e.startsWith(vn)||e.startsWith(bi)||e.startsWith("file:"))t=wn(e);else{if(e.includes("://")||e.startsWith("#")||e.startsWith("//"))return null;t=wn(e)}if(t.startsWith("/")&&t.split("/").filter(Boolean).length<2)return null;const n=t.split("/").pop()||"",r=n.lastIndexOf(".");if(r<=0)return null;const i=n.slice(r+1).toLowerCase();if(!i)return null;if(t.startsWith("/")){if(_x.has(i))return null}else if(!Ex.has(i))return null;return t}function Tx(e){return e>=1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:e>=1024?`${Math.round(e/1024)} KB`:`${e} B`}const ei=({size:e=20,style:t})=>h.jsxs("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:t,"aria-hidden":"true",children:[h.jsx("path",{d:"M15.3929 4.05365L14.8912 4.61112L15.3929 4.05365ZM19.3517 7.61654L18.85 8.17402L19.3517 7.61654ZM21.654 10.1541L20.9689 10.4592V10.4592L21.654 10.1541ZM3.17157 20.8284L3.7019 20.2981H3.7019L3.17157 20.8284ZM20.8284 20.8284L20.2981 20.2981L20.2981 20.2981L20.8284 20.8284ZM14 21.25H10V22.75H14V21.25ZM2.75 14V10H1.25V14H2.75ZM21.25 13.5629V14H22.75V13.5629H21.25ZM14.8912 4.61112L18.85 8.17402L19.8534 7.05907L15.8947 3.49618L14.8912 4.61112ZM22.75 13.5629C22.75 11.8745 22.7651 10.8055 22.3391 9.84897L20.9689 10.4592C21.2349 11.0565 21.25 11.742 21.25 13.5629H22.75ZM18.85 8.17402C20.2034 9.3921 20.7029 9.86199 20.9689 10.4592L22.3391 9.84897C21.9131 8.89241 21.1084 8.18853 19.8534 7.05907L18.85 8.17402ZM10.0298 2.75C11.6116 2.75 12.2085 2.76158 12.7405 2.96573L13.2779 1.5653C12.4261 1.23842 11.498 1.25 10.0298 1.25V2.75ZM15.8947 3.49618C14.8087 2.51878 14.1297 1.89214 13.2779 1.5653L12.7405 2.96573C13.2727 3.16993 13.7215 3.55836 14.8912 4.61112L15.8947 3.49618ZM10 21.25C8.09318 21.25 6.73851 21.2484 5.71085 21.1102C4.70476 20.975 4.12511 20.7213 3.7019 20.2981L2.64124 21.3588C3.38961 22.1071 4.33855 22.4392 5.51098 22.5969C6.66182 22.7516 8.13558 22.75 10 22.75V21.25ZM1.25 14C1.25 15.8644 1.24841 17.3382 1.40313 18.489C1.56076 19.6614 1.89288 20.6104 2.64124 21.3588L3.7019 20.2981C3.27869 19.8749 3.02502 19.2952 2.88976 18.2892C2.75159 17.2615 2.75 15.9068 2.75 14H1.25ZM14 22.75C15.8644 22.75 17.3382 22.7516 18.489 22.5969C19.6614 22.4392 20.6104 22.1071 21.3588 21.3588L20.2981 20.2981C19.8749 20.7213 19.2952 20.975 18.2892 21.1102C17.2615 21.2484 15.9068 21.25 14 21.25V22.75ZM21.25 14C21.25 15.9068 21.2484 17.2615 21.1102 18.2892C20.975 19.2952 20.7213 19.8749 20.2981 20.2981L21.3588 21.3588C22.1071 20.6104 22.4392 19.6614 22.5969 18.489C22.7516 17.3382 22.75 15.8644 22.75 14H21.25ZM2.75 10C2.75 8.09318 2.75159 6.73851 2.88976 5.71085C3.02502 4.70476 3.27869 4.12511 3.7019 3.7019L2.64124 2.64124C1.89288 3.38961 1.56076 4.33855 1.40313 5.51098C1.24841 6.66182 1.25 8.13558 1.25 10H2.75ZM10.0298 1.25C8.15538 1.25 6.67442 1.24842 5.51887 1.40307C4.34232 1.56054 3.39019 1.8923 2.64124 2.64124L3.7019 3.7019C4.12453 3.27928 4.70596 3.02525 5.71785 2.88982C6.75075 2.75158 8.11311 2.75 10.0298 2.75V1.25Z",fill:"currentColor"}),h.jsx("path",{d:"M6 14.5H14",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),h.jsx("path",{d:"M6 18H11.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),h.jsx("path",{d:"M13 2.5V5C13 7.35702 13 8.53553 13.7322 9.26777C14.4645 10 15.643 10 18 10H22",stroke:"currentColor",strokeWidth:"1.5"})]}),Ho=({path:e,onGetFileInfo:t,onDownload:n})=>{const{t:r}=Ye(),[i,o]=N.useState({status:"loading"}),a=N.useRef(t);a.current=t,N.useEffect(()=>{let g=!1;return a.current(e).then(({name:k,size:S,mimeType:x})=>{g||o({status:"ready",name:k,size:S,mimeType:x})}).catch(k=>{g||o({status:"error",message:k instanceof Error?k.message:String(k)})}),()=>{g=!0}},[e]);const l=N.useCallback(async()=>{if(i.status!=="ready"&&i.status!=="done")return;const g=i;o({status:"downloading",name:g.name,size:g.size,mimeType:g.mimeType,progress:0});try{await n(e,(k,S)=>{o(x=>x.status!=="downloading"?x:{...x,progress:S>0?k/S:0})}),o({status:"done",name:g.name,size:g.size,mimeType:g.mimeType})}catch{o({status:"ready",name:g.name,size:g.size,mimeType:g.mimeType})}},[i,e,n]),s={display:"inline-flex",alignItems:"center",gap:"10px",padding:"10px 14px",border:"1px solid var(--bf-color-border-subtle)",borderRadius:"10px",background:"var(--bf-color-surface-subtle)",cursor:i.status==="ready"||i.status==="done"?"pointer":"default",maxWidth:"300px",verticalAlign:"middle",transition:"background 0.15s"},u="var(--bf-color-content-muted)";if(i.status==="loading")return h.jsxs("span",{className:"file-card",style:s,children:[h.jsx(ei,{size:20,style:{color:u,flexShrink:0}}),h.jsx("span",{style:{fontSize:"0.8rem",opacity:.5},children:r("chat.fileLoading")})]});if(i.status==="error")return h.jsxs("span",{className:"file-card",style:{...s,cursor:"default",opacity:.5},title:i.message,children:[h.jsx(ei,{size:20,style:{color:u,flexShrink:0}}),h.jsx("span",{style:{fontSize:"0.8rem"},children:r("chat.fileUnavailable")})]});const{name:p,size:c}=i,f=i.status==="downloading",d=i.status==="done";return h.jsxs("span",{className:"file-card",style:s,onClick:l,role:"button",tabIndex:0,onKeyDown:g=>{(g.key==="Enter"||g.key===" ")&&l()},title:r(f?"chat.fileDownloading":d?"chat.fileDownloaded":"chat.clickToDownload"),children:[h.jsx(ei,{size:20,style:{color:u,flexShrink:0}}),h.jsxs("span",{style:{minWidth:0,overflow:"hidden"},children:[h.jsx("span",{style:{display:"block",fontSize:"0.85rem",fontWeight:500,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"var(--bf-color-content-primary)"},children:p}),h.jsx("span",{style:{display:"block",fontSize:"0.75rem",color:"var(--bf-color-content-muted)",marginTop:"2px"},children:Tx(c)})]}),h.jsx("span",{style:{flexShrink:0,fontSize:"0.75rem",color:d?"var(--bf-color-status-success-content)":"var(--bf-color-content-muted)"},children:f?`${Math.round(i.progress*100)}%`:d?"✓":"↓"})]})},Kt=({content:e,onFileDownload:t,onGetFileInfo:n})=>{const{isDark:r}=Zo(),i=r?Fy:My,o=N.useMemo(()=>({code({className:a,children:l,...s}){const u=/language-(\w+)/.exec(a||""),p=String(l).replace(/\n$/,""),c=p.includes(`
+`);return a?.startsWith("language-")||c?h.jsxs("div",{className:"code-block-wrapper",children:[h.jsx(Sx,{code:p}),h.jsx($e,{language:u?.[1]||"text",style:i,showLineNumbers:!0,customStyle:{margin:0,borderRadius:"8px",fontSize:"0.8rem",lineHeight:"1.5"},codeTagProps:{style:{fontFamily:"var(--font-family-mono)"}},lineNumberStyle:{color:"var(--bf-color-content-muted)",paddingRight:"1em",textAlign:"right",userSelect:"none",minWidth:"2.5em"},children:p})]}):h.jsx("code",{className:"inline-code",...s,children:l})},a({href:a,children:l}){const s=typeof a=="string"&&a.startsWith(vn);if(s&&n&&t){const u=wn(a);return h.jsx(Ho,{path:u,onGetFileInfo:n,onDownload:t})}if(s&&t){const u=wn(a);return h.jsx("button",{className:"file-link",onClick:p=>{p.preventDefault(),p.stopPropagation(),t(u)},type:"button",style:{cursor:"pointer",color:"var(--bf-color-accent-default)",textDecoration:"underline",background:"none",border:"none",font:"inherit",padding:0},children:l})}if(n&&t){const u=typeof a=="string"?Cx(a):null;if(u)return h.jsx(Ho,{path:u,onGetFileInfo:n,onDownload:t})}return typeof a=="string"&&(a.startsWith("http://")||a.startsWith("https://"))?h.jsx("a",{href:a,target:"_blank",rel:"noopener noreferrer",style:{color:"var(--bf-color-accent-default)",textDecoration:"underline"},children:l}):h.jsx("span",{style:{textDecoration:"underline",opacity:.7},children:l})},table({children:a}){return h.jsx("div",{className:"table-wrapper",children:h.jsx("table",{children:a})})},blockquote({children:a}){return h.jsx("blockquote",{className:"custom-blockquote",children:a})}}),[i,r,t,n]);return h.jsx(uf,{remarkPlugins:[Sg],components:o,urlTransform:a=>a.startsWith("computer://")||/^(https?|mailto|tel|file):/i.test(a)||a.startsWith("#")||a.startsWith("/")||!a.includes(":")?a:"",children:e})},xi=({thinking:e,streaming:t,isLastItem:n=!1})=>{const{t:r}=Ye(),[i,o]=N.useState(!!t),a=N.useRef(!1),l=N.useRef(null),[s,u]=N.useState({atTop:!0,atBottom:!0}),p=Cs(e,!!t);N.useEffect(()=>{a.current||(t?o(!0):n||o(!1))},[t,n]),N.useEffect(()=>{if(!t||!i)return;const k=l.current;if(!k)return;k.scrollHeight-k.scrollTop-k.clientHeight<80&&(k.scrollTop=k.scrollHeight)},[p,t,i]);const c=N.useCallback(()=>{const k=l.current;k&&u({atTop:k.scrollTop<4,atBottom:k.scrollHeight-k.scrollTop-k.clientHeight<4})},[]),f=N.useCallback(()=>{a.current=!0,o(k=>!k)},[]);if(!e&&!t)return null;const d=e.length,g=t&&d===0?r("chat.thinking"):r("chat.thoughtCharacters",{count:d});return h.jsxs("div",{className:`chat-thinking ${t?"chat-thinking--streaming":""}`,children:[h.jsxs("button",{className:"chat-thinking__toggle",onClick:f,children:[h.jsx("span",{className:`chat-thinking__chevron ${i?"is-open":""}`,children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M6 4L10 8L6 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsx("span",{className:"chat-thinking__label",children:g})]}),h.jsx("div",{className:`chat-thinking__expand-container ${i?"is-expanded":""}`,children:h.jsx("div",{className:"chat-thinking__expand-inner",children:e&&h.jsx("div",{className:`chat-thinking__content-wrapper ${s.atTop?"at-top":""} ${s.atBottom?"at-bottom":""}`,ref:l,onScroll:c,children:h.jsx("div",{className:"chat-thinking__content",children:h.jsx(Kt,{content:t?p:e})})})})})]})},Sn={explore:"shared.tools.explore",read_file:"shared.tools.read",write_file:"shared.tools.write",list_directory:"tools.ls",bash:"shared.tools.shell",glob:"tools.glob",grep:"tools.grep",create_file:"shared.tools.write",delete_file:"tools.delete",Task:"tools.task",search:"shared.tools.search",edit_file:"shared.tools.edit",web_search:"tools.web",TodoWrite:"shared.tools.todo"},Ax=({tool:e})=>{const{t}=Ye(),[n,r]=N.useState(!1),i=N.useMemo(()=>{const u=e.tool_input;if(!u)return[];const p=u.todos||u.result?.todos;return Array.isArray(p)?p:[]},[e.tool_input]);if(i.length===0)return null;const o=i.filter(u=>u.status==="completed").length,a=o===i.length,l=i.find(u=>u.status==="in_progress"),s=u=>{switch(u){case"completed":return h.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"var(--bf-color-status-success-content)",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("path",{d:"M22 11.08V12a10 10 0 1 1-5.93-9.14"}),h.jsx("path",{d:"m9 11 3 3L22 4"})]});case"in_progress":return h.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"var(--bf-color-accent-default)",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("circle",{cx:"12",cy:"12",r:"10"}),h.jsx("polygon",{points:"10 8 16 12 10 16 10 8",fill:"var(--bf-color-accent-default)"})]});case"cancelled":return h.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"var(--bf-color-status-danger-content)",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("circle",{cx:"12",cy:"12",r:"10"}),h.jsx("path",{d:"m15 9-6 6"}),h.jsx("path",{d:"m9 9 6 6"})]});default:return h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"var(--bf-color-content-muted)",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("circle",{cx:"12",cy:"12",r:"10"})})}};return h.jsxs("div",{className:"chat-todo-card",children:[h.jsxs("div",{className:"chat-todo-card__header",onClick:()=>r(!n),children:[h.jsx("span",{className:"chat-todo-card__icon",children:h.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("rect",{x:"3",y:"5",width:"6",height:"6",rx:"1"}),h.jsx("path",{d:"m3 17 2 2 4-4"}),h.jsx("path",{d:"M13 6h8"}),h.jsx("path",{d:"M13 12h8"}),h.jsx("path",{d:"M13 18h8"})]})}),a&&!n?h.jsx("span",{className:"chat-todo-card__current chat-todo-card__current--done",children:t("chat.allTasksCompleted")}):l&&!n?h.jsx("span",{className:"chat-todo-card__current",children:l.content}):null,h.jsxs("span",{className:"chat-todo-card__right",children:[h.jsx("span",{className:"chat-todo-card__dots",children:i.map((u,p)=>h.jsx("span",{className:`chat-todo-card__dot chat-todo-card__dot--${u.status}`},u.id||p))}),h.jsxs("span",{className:"chat-todo-card__stats",children:[o,"/",i.length]})]}),h.jsx("span",{className:`chat-todo-card__chevron ${n?"is-expanded":""}`,children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("path",{d:"m6 9 6 6 6-6"})})})]}),n&&h.jsx("div",{className:"chat-todo-card__list",children:i.map((u,p)=>h.jsxs("div",{className:`chat-todo-card__item chat-todo-card__item--${u.status}`,children:[s(u.status),h.jsx("span",{className:"chat-todo-card__item-text",children:u.content})]},u.id||p))})]})};function Lx(e){const t=e.tool_input??(()=>{try{return JSON.parse(e.input_preview||"")}catch{return null}})();return t?{description:t.description,agentType:t.subagent_type}:null}function Nx(e,t){if(e.type==="thinking"){const n=(e.content||"").length;return t("chat.thoughtCharacters",{count:n})}if(e.type==="tool"&&e.tool){const n=e.tool,r=n.input_preview?`: ${n.input_preview}`:"";return`${n.name}${r}`}if(e.type==="text"){const n=(e.content||"").length;return t("chat.textCharacters",{count:n})}return""}const _s=({tool:e,now:t,subItems:n=[],onCancelTool:r})=>{const{t:i,language:o}=Ye(),a=N.useRef(null),l=N.useRef(0),[s,u]=N.useState(!1),p=e.status==="running",c=e.status==="completed",f=e.status==="failed"||e.status==="error",d=p&&!!r,g=Lx(e),k=c&&e.duration_ms!=null?Wt(e.duration_ms):p&&e.start_ms?Wt(t-e.start_ms):"",S=p?"running":c?"done":f?"error":"pending",x=n.filter(_=>_.type==="tool"&&_.tool),v=x.filter(_=>_.tool.status==="completed").length,b=x.filter(_=>_.tool.status==="running").length;return N.useEffect(()=>{s&&n.length>l.current&&a.current&&(a.current.scrollTop=a.current.scrollHeight),l.current=n.length},[n.length,s]),h.jsxs("div",{className:`chat-task-card chat-task-card--${S}`,children:[h.jsxs("div",{className:"chat-task-card__header",children:[h.jsx("span",{className:"chat-tool-card__icon",children:p?h.jsx("span",{className:"chat-tool-card__spinner"}):c?h.jsx("span",{className:"chat-tool-card__check",children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M3 8.5L6.5 12L13 4",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}):f?h.jsx("span",{className:"chat-tool-card__error-icon",children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M4 4L12 12M12 4L4 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})})}):h.jsx("span",{className:"chat-tool-card__spinner"})}),h.jsx("span",{className:"chat-tool-card__name",children:g?.description||i("chat.task")}),g?.agentType&&h.jsx("span",{className:"chat-tool-card__type",children:g.agentType}),k&&h.jsx("span",{className:"chat-tool-card__duration",children:k}),d&&h.jsx("button",{className:"chat-tool-card__cancel",onClick:_=>{_.stopPropagation(),r?.(e.id)},"aria-label":i("common.cancel"),children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("rect",{x:"3",y:"3",width:"10",height:"10",rx:"2",fill:"currentColor"})})})]}),n.length>0&&h.jsxs(h.Fragment,{children:[h.jsxs("div",{className:"chat-task-card__summary",onClick:()=>u(_=>!_),children:[h.jsx("span",{className:"chat-task-card__stat",children:i("chat.toolCalls",{count:x.length,suffix:Hi(o,x.length)})}),h.jsxs("span",{className:"chat-task-card__stat-right",children:[h.jsx("span",{className:"chat-task-card__stat--done",children:i("chat.done",{count:v})}),b>0&&h.jsx("span",{className:"chat-task-card__stat--running",children:i("chat.running",{count:b})})]}),h.jsx("span",{className:`chat-task-card__chevron ${s?"is-expanded":""}`,children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("path",{d:"m6 9 6 6 6-6"})})})]}),s&&h.jsx("div",{className:"chat-task-card__steps",ref:a,children:n.map((_,C)=>{if(_.type==="thinking")return h.jsxs("div",{className:"chat-task-card__step chat-task-card__step--thinking",children:[h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("path",{d:"m6 9 6 6 6-6"})}),h.jsx("span",{children:Nx(_,i)})]},`sub-think-${C}`);if(_.type==="tool"&&_.tool){const m=_.tool,T=m.status==="completed",j=m.status==="failed"||m.status==="error";return h.jsxs("div",{className:`chat-task-card__step chat-task-card__step--tool ${T?"is-done":j?"is-error":"is-running"}`,children:[T?h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M3 8.5L6.5 12L13 4",stroke:"var(--bf-color-status-success-content)",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}):j?h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M4 4L12 12M12 4L4 12",stroke:"var(--bf-color-status-danger-content)",strokeWidth:"2",strokeLinecap:"round"})}):h.jsx("span",{className:"chat-task-card__step-spinner"}),h.jsx("span",{className:"chat-task-card__step-name",children:m.name}),(()=>{const A=Es(m);return A?h.jsx("span",{className:"chat-task-card__step-preview",children:A}):null})(),T&&m.duration_ms!=null&&h.jsx("span",{className:"chat-task-card__step-duration",children:Wt(m.duration_ms)})]},`sub-tool-${m.id}-${C}`)}return null})})]})]})};function Es(e){if(!e.input_preview)return null;try{const t=JSON.parse(e.input_preview);if(!t||typeof t!="object")return null;const n=o=>{const a=o.replace(/\\/g,"/").split("/");return a[a.length-1]||o};let r=null;const i=t.file_path||t.path;switch(e.name){case"Read":case"Write":case"Edit":case"LS":case"StrReplace":case"delete_file":r=i?n(i):null;break;case"Glob":case"Grep":r=t.pattern||null;break;case"Bash":case"Shell":r=t.description||t.command||null;break;case"web_search":case"WebSearch":r=t.search_term||t.query||null;break;case"WebFetch":r=t.url||null;break;case"SemanticSearch":r=t.query||null;break;default:r=Object.values(t).find(a=>typeof a=="string"&&a.length>0&&a.length<80)||null}return r?r.length>60?r.slice(0,60)+"…":r:null}catch{return null}}const Wo=({tool:e,now:t,onCancelTool:n})=>{const{t:r}=Ye(),i=e.name.toLowerCase().replace(/[\s-]/g,"_"),o=Sn[i]||Sn[e.name],a=o?r(o):"Tool",l=e.status==="running",s=e.status==="completed",u=e.status==="failed"||e.status==="error",p=l&&!!n,c=Es(e),f=s&&e.duration_ms!=null?Wt(e.duration_ms):l&&e.start_ms?Wt(t-e.start_ms):"",d=l?"running":s?"done":u?"error":"pending";return h.jsx("div",{className:`chat-tool-card chat-tool-card--${d}`,children:h.jsxs("div",{className:"chat-tool-card__row",children:[h.jsx("span",{className:"chat-tool-card__icon",children:l?h.jsx("span",{className:"chat-tool-card__spinner"}):s?h.jsx("span",{className:"chat-tool-card__check",children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M3 8.5L6.5 12L13 4",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}):u?h.jsx("span",{className:"chat-tool-card__error-icon",children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M4 4L12 12M12 4L4 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})})}):h.jsx("span",{className:"chat-tool-card__spinner"})}),h.jsxs("span",{className:"chat-tool-card__name",children:[e.name,c&&h.jsxs("span",{className:"chat-tool-card__preview",children:[" ",c]})]}),h.jsx("span",{className:"chat-tool-card__type",children:a}),f&&h.jsx("span",{className:"chat-tool-card__duration",children:f}),p&&h.jsx("button",{className:"chat-tool-card__cancel",onClick:g=>{g.stopPropagation(),n?.(e.id)},"aria-label":r("common.cancel"),children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("rect",{x:"3",y:"3",width:"10",height:"10",rx:"2",fill:"currentColor"})})})]})})},Ix=new Set(["Read","Grep","Glob","SemanticSearch"]);function jx(e,t){const n=new Map,r=[];for(const i of e){const o=i.name.toLowerCase().replace(/[\s-]/g,"_"),a=Sn[o]||Sn[i.name],l=a?t(a):i.name,s=l.toLowerCase(),u=n.get(s);if(u){u.count+=1;continue}n.set(s,{label:l,count:1}),r.push(s)}return r.map(i=>{const o=n.get(i);return`${o.label} ${o.count}`}).join(", ")}const Rx=({tools:e})=>{const{t}=Ye(),[n,r]=N.useState(!1);if(e.length===0)return null;const i=e.filter(s=>s.status==="completed").length,o=i===e.length,a=jx(e,t),l=o?t("chat.readToolsDone",{summary:a}):t("chat.readToolsRunning",{summary:a,doneCount:i});return h.jsxs("div",{className:`chat-thinking ${o?"":"chat-thinking--streaming"}`,children:[h.jsxs("button",{className:"chat-thinking__toggle",onClick:()=>r(s=>!s),children:[h.jsx("span",{className:`chat-thinking__chevron ${n?"is-open":""}`,children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M6 4L10 8L6 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsx("span",{className:"chat-thinking__label",children:l})]}),n&&h.jsx("div",{className:"chat-thinking__content-wrapper at-top at-bottom",children:h.jsx("div",{className:"chat-thinking__content",children:e.map(s=>{const u=s.input_preview||"";return h.jsxs("div",{style:{fontSize:"12px",padding:"2px 0",opacity:.8},children:[s.status==="completed"?"✓":"⋯"," ",s.name," ",u]},s.id)})})})]})},Ox=2,ki=({tools:e,now:t,onCancelTool:n})=>{const{t:r,language:i}=Ye(),o=N.useRef(null),a=N.useRef(0),[l,s]=N.useState(!1);if(N.useEffect(()=>{l&&e.length>a.current&&o.current&&(o.current.scrollTop=o.current.scrollHeight),a.current=e.length},[e.length,l]),!e||e.length===0)return null;if(e.length<=Ox)return h.jsx("div",{className:"chat-tool-list",children:e.map(c=>h.jsx(Wo,{tool:c,now:t,onCancelTool:n},c.id))});const u=e.filter(c=>c.status==="running").length,p=e.filter(c=>c.status==="completed").length;return h.jsxs("div",{className:"chat-tool-list chat-tool-list--collapsed",children:[h.jsxs("div",{className:"chat-tool-list__header",onClick:()=>s(c=>!c),children:[h.jsx("span",{className:"chat-tool-list__count",children:r("chat.toolCalls",{count:e.length,suffix:Hi(i,e.length)})}),h.jsxs("span",{className:"chat-tool-list__stats",children:[p>0&&h.jsx("span",{className:"chat-tool-list__stat chat-tool-list__stat--done",children:r("chat.done",{count:p})}),u>0&&h.jsx("span",{className:"chat-tool-list__stat chat-tool-list__stat--running",children:r("chat.running",{count:u})})]}),h.jsx("span",{className:`chat-tool-list__chevron ${l?"is-expanded":""}`,children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("path",{d:"m6 9 6 6 6-6"})})})]}),l&&h.jsx("div",{className:"chat-tool-list__scroll",ref:o,children:e.map(c=>h.jsx(Wo,{tool:c,now:t,onCancelTool:n},c.id))})]})},ti=()=>h.jsxs("span",{className:"chat-msg__typing",children:[h.jsx("span",{}),h.jsx("span",{}),h.jsx("span",{})]});function Cs(e,t){const[n,r]=N.useState(t?"":e),i=N.useRef(t?0:e.length),o=N.useRef(e),a=N.useRef(null),l=N.useRef(3);return N.useEffect(()=>{if(!t){a.current&&(clearInterval(a.current),a.current=null),i.current=e.length,o.current=e,r(e);return}o.current=e,e.length0){const c=26.666666666666668;l.current=Math.max(Math.ceil(s/c),2),a.current||(a.current=setInterval(()=>{const f=o.current,d=i.current;if(d>=f.length){a.current&&(clearInterval(a.current),a.current=null);return}const g=Math.min(d+l.current,f.length);i.current=g,r(f.slice(0,g))},30))}},[e,t]),N.useEffect(()=>()=>{a.current&&clearInterval(a.current)},[]),n}const Ts=({content:e,onFileDownload:t,onGetFileInfo:n})=>{const r=Cs(e,!0);return h.jsx(Kt,{content:r,onFileDownload:t,onGetFileInfo:n})},_n=e=>!e||e.name!=="AskUserQuestion"||!e.tool_input?!1:!["completed","failed","cancelled","rejected"].includes(e.status);function Dx(e,t){const n=t.split(".");let r=e;for(const i of n){if(!r||typeof r!="object"||!(i in r))return null;r=r[i]}return typeof r=="string"?r:null}const Mx=new Set(["other",...Object.values(Ys).map(e=>Dx(e,"common.other")).filter(e=>!!e).map(e=>e.trim().toLowerCase())]),xt=e=>{const t=(e||"").trim().toLowerCase();return Mx.has(t)},As=({tool:e,onAnswer:t})=>{const{t:n,language:r}=Ye(),i=e.tool_input?.questions||[],[o,a]=N.useState({}),[l,s]=N.useState({}),[u,p]=N.useState(!1),[c,f]=N.useState(!1),d=N.useMemo(()=>i.map(x=>{const v=Array.isArray(x.options)?x.options:[],b=v.some(_=>xt(_?.label));return{...x,options:v,hasBuiltInOther:b}}),[i]);if(d.length===0)return null;const g=(x,v,b)=>{a(_=>{if(b){const C=_[x]||[];return{..._,[x]:C.includes(v)?C.filter(m=>m!==v):[...C,v]}}return{..._,[x]:_[x]===v?void 0:v}})},k=async()=>{if(!S||u||c)return;const x={};d.forEach((v,b)=>{const _=o[b],C=(l[b]||"").trim();Array.isArray(_)?x[String(b)]=_.map(m=>xt(m)&&C||m):xt(_)?x[String(b)]=C||_:x[String(b)]=_??""}),p(!0);try{await t(e.id,x),f(!0)}finally{p(!1)}},S=d.every((x,v)=>{const b=o[v];return(x.multiSelect?Array.isArray(b)&&b.length>0:!!b)?!(Array.isArray(b)?b.some(m=>xt(m)):xt(b))||!!(l[v]||"").trim():!1});return h.jsxs("div",{className:"chat-ask-card",children:[h.jsxs("div",{className:"chat-ask-card__header",children:[h.jsx("span",{className:"chat-ask-card__count",children:n("chat.askQuestionCount",{count:i.length,suffix:Hi(r,i.length)})}),!c&&!u&&h.jsx("span",{className:"chat-ask-card__waiting",children:n("chat.waiting")})]}),d.map((x,v)=>{const b=o[v],_=Array.isArray(b)?b.some(C=>xt(C)):xt(b);return h.jsxs("div",{className:"chat-ask-card__question",children:[h.jsxs("div",{className:"chat-ask-card__question-header",children:[h.jsx("span",{className:"chat-ask-card__tag",children:x.header}),h.jsx("span",{className:"chat-ask-card__question-text",children:x.question})]}),h.jsxs("div",{className:"chat-ask-card__options",children:[(x.options||[]).map((C,m)=>{const T=x.multiSelect?(o[v]||[]).includes(C.label):o[v]===C.label;return h.jsxs("button",{className:`chat-ask-card__option ${T?"is-selected":""}`,onClick:()=>g(v,C.label,x.multiSelect),disabled:c||u,children:[h.jsx("span",{className:`chat-ask-card__radio ${x.multiSelect?"chat-ask-card__radio--multi":""}`,children:T&&h.jsx("svg",{width:"8",height:"8",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M3 8L6.5 11.5L13 4.5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsx("span",{className:"chat-ask-card__option-label",children:C.label}),C.description&&h.jsx("span",{className:"chat-ask-card__option-desc",children:C.description})]},m)}),!x.hasBuiltInOther&&h.jsxs("button",{className:`chat-ask-card__option ${_?"is-selected":""}`,onClick:()=>g(v,"Other",x.multiSelect),disabled:c||u,children:[h.jsx("span",{className:`chat-ask-card__radio ${x.multiSelect?"chat-ask-card__radio--multi":""}`,children:_&&h.jsx("svg",{width:"8",height:"8",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M3 8L6.5 11.5L13 4.5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsx("span",{className:"chat-ask-card__option-label",children:n("common.other")}),h.jsx("span",{className:"chat-ask-card__option-desc",children:n("common.customTextInput")})]}),_&&h.jsx("input",{className:"chat-ask-card__custom-input",placeholder:n("common.typeYourAnswer"),value:l[v]||"",onChange:C=>s(m=>({...m,[v]:C.target.value})),disabled:c||u})]})]},v)}),h.jsxs("button",{className:"chat-ask-card__submit chat-ask-card__submit--bottom",disabled:!S||c||u,onClick:k,children:[h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M2 8L6 12L14 4",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}),n(c?"common.submitted":u?"common.submitting":"common.submit")]})]})};function Ls(e){const t=[];let n=null;for(const r of e){if(r.type==="tool"&&r.tool?.name==="Task"){const i={...r,subItems:[]};t.push(i),n=i;continue}if(r.is_subagent&&n){n.subItems.push(r);continue}r.is_subagent||t.push(r)}return t}function Nt(e){const t=[];for(const n of e){const r=t[t.length-1];r&&r.type===n.type?r.entries.push(n):t.push({type:n.type,entries:[n]})}return t}function Ns(e,t,n){return n?e.map((r,i)=>h.jsx(As,{tool:r.tool,onAnswer:n},`${t}-ask-${r.tool.id}-${i}`)):null}function It(e,t,n,r,i,o,a,l){return e.map((s,u)=>{if(s.type==="thinking"){const p=s.entries.map(f=>f.content||"").join(`
-`),c=l&&u===e.length-1;return h.jsx(xi,{thinking:p,streaming:c,isLastItem:c},`${t}-thinking-${u}`)}if(s.type==="tool"){const p=[];let c=[],f=[];const d=()=>{f.length>0&&(p.push(h.jsx(Rx,{tools:f},`${t}-read-${u}-${p.length}`)),f=[])},g=()=>{c.length>0&&(p.push(h.jsx(ki,{tools:c,now:n,onCancelTool:r},`${t}-tl-${u}-${p.length}`)),c=[])},k=()=>{d(),g()};for(const S of s.entries)S.tool?.name==="Task"?(k(),p.push(h.jsx(_s,{tool:S.tool,now:n,subItems:S.subItems,onCancelTool:r},`${t}-task-${u}-${p.length}`))):S.tool?.name==="TodoWrite"?(k(),p.push(h.jsx(Ax,{tool:S.tool},`${t}-todo-${u}-${p.length}`))):S.tool&&Ix.has(S.tool.name)?(g(),f.push(S.tool)):S.tool&&(d(),c.push(S.tool));return k(),h.jsx(it.Fragment,{children:p},`${t}-tool-${u}`)}if(s.type==="text"){const p=s.entries.map(c=>c.content||"").join("");return p?h.jsx("div",{className:"chat-msg__assistant-content",children:i?h.jsx(Ts,{content:p,onFileDownload:o,onGetFileInfo:a}):h.jsx(Kt,{content:p,onFileDownload:o,onGetFileInfo:a})},`${t}-text-${u}`):null}return null})}function Vo(e,t,n,r,i,o){const a=Ls(e),l=a.filter(c=>_n(c.tool));if(l.length===0)return It(Nt(a),"ordered",t,n,!1,i,o);const s=[],u=[];let p=!1;for(const c of a)_n(c.tool)?p=!0:p?u.push(c):s.push(c);return h.jsxs(h.Fragment,{children:[It(Nt(s),"ordered-before",t,n,!1,i,o),Ns(l,"ordered",r),It(Nt(u),"ordered-after",t,n,!1,i,o)]})}function Fx(e,t,n,r,i,o,a,l){const s=Ls(e),u=s.filter(g=>_n(g.tool)),p=g=>{i()&&n.cancelTool(g,"User cancelled").catch(k=>{Je(k,r)})};if(u.length===0)return It(Nt(s),"active",t,p,!0,a,l,!0);const c=[],f=[];let d=!1;for(const g of s)_n(g.tool)?d=!0:d?f.push(g):c.push(g);return h.jsxs(h.Fragment,{children:[It(Nt(c),"active-before",t,p,!0,a,l,!0),Ns(u,"active",o),It(Nt(f),"active-after",t,p,!0,a,l,!0)]})}const zx=({isDark:e})=>h.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:e?h.jsx("path",{d:"M8 1.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM3 8a5 5 0 0 1 5-5v10a5 5 0 0 1-5-5Z",fill:"currentColor"}):h.jsx("path",{d:"M8 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 8 1Zm0 11a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 8 12Zm7-4a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1 0-1h1A.5.5 0 0 1 15 8ZM3 8a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1 0-1h1A.5.5 0 0 1 3 8Zm9.95-3.54a.5.5 0 0 1 0 .71l-.71.7a.5.5 0 1 1-.7-.7l.7-.71a.5.5 0 0 1 .71 0ZM5.46 11.24a.5.5 0 0 1 0 .71l-.7.71a.5.5 0 0 1-.71-.71l.7-.71a.5.5 0 0 1 .71 0Zm7.08 1.42a.5.5 0 0 1-.7 0l-.71-.71a.5.5 0 0 1 .7-.7l.71.7a.5.5 0 0 1 0 .71ZM5.46 4.76a.5.5 0 0 1-.71 0l-.71-.7a.5.5 0 0 1 .71-.71l.7.7a.5.5 0 0 1 0 .71ZM8 5a3 3 0 1 1 0 6 3 3 0 0 1 0-6Z",fill:"currentColor"})}),vi=({className:e,size:t=10})=>h.jsxs("svg",{className:e,width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[h.jsx("path",{d:"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.937A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .962 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.582a.5.5 0 0 1 0 .962L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.962 0z"}),h.jsx("path",{d:"M20 3v4"}),h.jsx("path",{d:"M22 5h-4"}),h.jsx("path",{d:"M4 17v2"}),h.jsx("path",{d:"M5 18H3"})]});function Is(e){const t=e.trim();return t?t.charAt(0).toUpperCase()+t.slice(1):"Unknown"}function Px(e){const t=e.name?.trim();return t||Is(e.provider)}function Bx(e){return e?`${Math.round(e/1e3)}k`:null}function $x(e){return e.enabled&&Array.isArray(e.capabilities)&&e.capabilities.includes("text_chat")}function ut(e,t){const n=e?.trim();if(!n||n==="primary")return"primary";if(n==="fast"){const r=t?.default_models?.fast;return r&&at(r,t)?n:"primary"}return at(n,t)?n:"primary"}function qx(){return typeof window>"u"?null:window.localStorage.getItem(bi)?.trim()||null}function ni(e){if(typeof window>"u")return;const t=e.trim();if(!t){window.localStorage.removeItem(bi);return}window.localStorage.setItem(bi,t)}function Ux(e,t){const n=e?.trim();if(!n)return{modelId:null,fallbackApplied:!1};const r=ut(n,t);return{modelId:r,fallbackApplied:r!==n}}function at(e,t){return t&&t.models.find(n=>n.id===e)||null}function js(e,t){const n=ut(e,t);return n==="primary"?at(t?.default_models?.primary||"",t):n==="fast"?at(t?.default_models?.fast||"",t)||at(t?.default_models?.primary||"",t):at(n,t)}function Vt(e){if(!e)return null;const t=[Px(e)],n=Bx(e.context_window);return n&&t.push(n),t.join(" · ")}function gn(e){return e&&(e.model_name||e.name)||""}function Go(e,t){if(e?.reasoning?.status!=="known")return;const n=t?.session_reasoning_preset?.trim();if(n)return e.reasoning.presets?.find(r=>r.id===n)?.label||n}function Hx(e,t,n){if(e==="primary"||e==="fast"){const i=js(e,t);return{label:n(e==="primary"?"chat.modelPrimary":"chat.modelFast"),meta:Vt(i)||n(e==="primary"?"chat.modelPrimaryDesc":"chat.modelFastDesc"),enableThinking:i?.reasoning?.status==="known",reasoningEffort:Go(i,t)}}const r=at(e,t);return r?{label:gn(r),meta:Vt(r),enableThinking:r.reasoning?.status==="known",reasoningEffort:Go(r,t)}:{label:n("chat.modelPrimary"),meta:n("chat.modelPrimaryDesc"),enableThinking:!1}}const Wx=({catalog:e,selectedModelId:t,disabled:n,onSelect:r})=>{const{t:i}=Ye(),[o,a]=N.useState(!1),l=N.useRef(null),s=N.useMemo(()=>ut(t,e),[e,t]),u=N.useMemo(()=>(e?.models||[]).filter($x),[e]),p=N.useMemo(()=>at(e?.default_models?.primary||"",e),[e]),c=N.useMemo(()=>at(e?.default_models?.fast||"",e),[e]),f=N.useMemo(()=>Hx(s,e,i),[e,s,i]);if(N.useEffect(()=>{if(!o)return;const g=k=>{l.current&&!l.current.contains(k.target)&&a(!1)};return document.addEventListener("mousedown",g),()=>document.removeEventListener("mousedown",g)},[o]),!e)return null;const d=async g=>{await r(g),a(!1)};return h.jsxs("div",{className:"chat-model-selector",ref:l,children:[h.jsxs("button",{className:`chat-model-selector__trigger${o?" chat-model-selector__trigger--open":""}`,type:"button",onClick:()=>a(g=>!g),disabled:n,"aria-label":i("chat.modelSelection"),children:[h.jsx("span",{className:"chat-model-selector__icon","aria-hidden":"true",children:h.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",children:[h.jsx("rect",{x:"4",y:"4",width:"6",height:"6",rx:"1.5",stroke:"currentColor",strokeWidth:"1.7"}),h.jsx("rect",{x:"14",y:"4",width:"6",height:"6",rx:"1.5",stroke:"currentColor",strokeWidth:"1.7"}),h.jsx("rect",{x:"9",y:"14",width:"6",height:"6",rx:"1.5",stroke:"currentColor",strokeWidth:"1.7"}),h.jsx("path",{d:"M10 7h4M12 10v4",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round"})]})}),h.jsxs("span",{className:"chat-model-selector__name",children:[h.jsx("span",{className:"chat-model-selector__name-text",children:f.label}),f.enableThinking&&h.jsx(vi,{className:"chat-model-selector__thinking",size:9})]}),f.reasoningEffort&&h.jsx("span",{className:"chat-model-selector__effort",children:f.reasoningEffort}),h.jsx("span",{className:"chat-model-selector__chevron","aria-hidden":"true",children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M4 6L8 10L12 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]}),o&&h.jsxs("div",{className:"chat-model-selector__dropdown",children:[h.jsx("div",{className:"chat-model-selector__header",children:i("chat.modelSelection")}),h.jsx("button",{className:`chat-model-selector__option${s==="primary"?" is-selected":""}`,type:"button",onClick:()=>{d("primary")},children:h.jsxs("span",{className:"chat-model-selector__option-main",children:[h.jsx("span",{className:"chat-model-selector__option-name",children:i("chat.modelPrimary")}),h.jsxs("span",{className:"chat-model-selector__option-meta chat-model-selector__option-meta--stacked",children:[h.jsx("span",{className:"chat-model-selector__option-meta-line",children:gn(p)||i("chat.modelPrimary")}),h.jsx("span",{className:"chat-model-selector__option-meta-line",children:Vt(p)||i("chat.modelPrimaryDesc")})]})]})}),h.jsx("button",{className:`chat-model-selector__option${s==="fast"?" is-selected":""}`,type:"button",onClick:()=>{d("fast")},children:h.jsxs("span",{className:"chat-model-selector__option-main",children:[h.jsx("span",{className:"chat-model-selector__option-name",children:i("chat.modelFast")}),h.jsxs("span",{className:"chat-model-selector__option-meta chat-model-selector__option-meta--stacked",children:[h.jsx("span",{className:"chat-model-selector__option-meta-line",children:gn(c)||i("chat.modelFast")}),h.jsx("span",{className:"chat-model-selector__option-meta-line",children:Vt(c)||i("chat.modelFastDesc")})]})]})}),h.jsx("div",{className:"chat-model-selector__divider"}),h.jsx("div",{className:"chat-model-selector__list",children:u.map(g=>{const k=s===g.id;return h.jsx("button",{className:`chat-model-selector__option${k?" is-selected":""}`,type:"button",onClick:()=>{d(g.id)},children:h.jsxs("span",{className:"chat-model-selector__option-main",children:[h.jsxs("span",{className:"chat-model-selector__option-name",children:[h.jsx("span",{className:"chat-model-selector__option-name-text",children:gn(g)}),g.reasoning?.status==="known"&&h.jsx(vi,{className:"chat-model-selector__option-thinking",size:10})]}),h.jsx("span",{className:"chat-model-selector__option-meta",children:Vt(g)||Is(g.provider)})]})},g.id)})})]})]})},Vx=({catalog:e,selectedModelId:t,disabled:n,onSelect:r})=>{const{t:i}=Ye(),[o,a]=N.useState(!1),l=N.useRef(null),s=N.useMemo(()=>js(t,e),[e,t]),u=N.useMemo(()=>[...s?.reasoning?.presets||[]].sort((k,S)=>k.order-S.order),[s]),p=e?.session_reasoning_preset?.trim()||null,c=p?u.find(k=>k.id===p)?.label||p:i("chat.reasoningAuto"),f=e?.reasoning_preset_selection_supported===!0,d=n||!f;if(N.useEffect(()=>{if(!o)return;const k=S=>{l.current&&!l.current.contains(S.target)&&a(!1)};return document.addEventListener("mousedown",k),()=>document.removeEventListener("mousedown",k)},[o]),s?.reasoning?.status!=="known"||u.length===0)return null;const g=async k=>{await r(k),a(!1)};return h.jsxs("div",{className:"chat-model-selector chat-reasoning-selector",ref:l,children:[h.jsxs("button",{className:`chat-model-selector__trigger chat-reasoning-selector__trigger${o?" chat-model-selector__trigger--open":""}`,type:"button",onClick:()=>a(k=>!k),disabled:d,"aria-label":i("chat.reasoningSelection"),children:[h.jsx(vi,{className:"chat-model-selector__thinking",size:10}),h.jsx("span",{className:"chat-model-selector__name chat-reasoning-selector__name",children:h.jsx("span",{className:"chat-model-selector__name-text",children:c})}),h.jsx("span",{className:"chat-model-selector__chevron","aria-hidden":"true",children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M4 6L8 10L12 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]}),o&&f&&h.jsxs("div",{className:"chat-model-selector__dropdown chat-reasoning-selector__dropdown",children:[h.jsx("div",{className:"chat-model-selector__header",children:i("chat.reasoningSelection")}),h.jsxs("div",{className:"chat-model-selector__list",children:[h.jsx("button",{className:`chat-model-selector__option${p===null?" is-selected":""}`,type:"button",onClick:()=>{g(null)},children:h.jsx("span",{className:"chat-model-selector__option-name",children:i("chat.reasoningAuto")})}),u.map(k=>h.jsx("button",{className:`chat-model-selector__option${p===k.id?" is-selected":""}`,type:"button",onClick:()=>{g(k.id)},children:h.jsx("span",{className:"chat-model-selector__option-name",children:k.label})},k.id))]})]})]})},Zx=({sessionMgr:e,sessionId:t,sessionName:n,onBack:r,autoFocus:i})=>{const{t:o}=Ye(),{getMessages:a,setMessages:l,appendNewMessages:s,activeTurn:u,setActiveTurn:p,error:c,setError:f,currentWorkspace:d,updateSessionName:g}=Ft(),{isDark:k,toggleTheme:S}=Zo(),x=a(t),[v,y]=N.useState(""),[_,C]=N.useState(n),[m,T]=N.useState(null),[j,A]=N.useState("primary"),[E,R]=N.useState(!1),[M,H]=N.useState([]),[P,z]=N.useState(!1),[G,J]=N.useState(null),[U,ie]=N.useState(!!i),w=N.useRef(null),K=N.useRef(null),Y=N.useRef(null),b=N.useRef(null),Z=N.useRef(0),[ee,te]=N.useState(!1),[xe,we]=N.useState(!0),_e=N.useRef(!1),Ce=N.useRef(!0),ye=Gs(e),qe=N.useRef({sessionMgr:e,sessionId:t,epoch:ye,active:!0});(qe.current.sessionMgr!==e||qe.current.sessionId!==t||qe.current.epoch!==ye)&&(qe.current={sessionMgr:e,sessionId:t,epoch:ye,active:!0});const le=N.useCallback(()=>{const I=qe.current;return!I.active||I.sessionMgr!==e||I.sessionId!==t||I.epoch!==e.controlTargetEpoch?null:I.epoch},[ye,t,e]),ce=N.useCallback(I=>{const O=qe.current;return I!==null&&O.active&&O.sessionMgr===e&&O.sessionId===t&&O.epoch===I&&e.controlTargetEpoch===I},[ye,t,e]),Ze=N.useRef(!1),Ae=N.useRef(0),Xe=N.useRef(null),Me=N.useRef(null),[dt,Fe]=N.useState(new Set),[Qe,Ue]=N.useState(null),[ft,He]=N.useState(!1),[se,L]=N.useState(null),[D,B]=N.useState(null),[V,re]=N.useState(!1),ke=N.useRef(),Te=N.useRef({x:0,y:0}),ve=N.useRef(),je=N.useRef({sessionMgr:e,sessionId:t,epoch:ye});N.useLayoutEffect(()=>{const I=je.current,O=I.sessionMgr!==e||I.sessionId!==t||I.epoch!==ye,$=qe.current;return $.active=$.sessionMgr===e&&$.sessionId===t&&$.epoch===ye&&e.controlTargetEpoch===ye,O&&(Z.current+=1,Ae.current+=1,_e.current=!1,Ce.current=!0,te(!1),we(!0),R(!1),z(!1),J(null),Ze.current=!1,T(null),A("primary"),l(t,[]),L(null),re(!1),B(null),Ue(null),Fe(new Set),He(!1),p(null),ke.current&&(clearTimeout(ke.current),ke.current=void 0),ve.current&&(clearTimeout(ve.current),ve.current=void 0),b.current?.stop(),b.current=null),je.current={sessionMgr:e,sessionId:t,epoch:ye},()=>{$.active=!1,Z.current+=1,Ae.current+=1,b.current?.stop()}},[ye,t,e,p,l]);const pe=u!=null&&u.status==="active",[Se,ze]=N.useState(()=>Date.now()),Le=N.useCallback(async(I,O)=>{const $=le();if($===null)throw new on;try{if(await e.answerQuestion(I,O),!ce($))throw new on}catch(q){throw Je(q,f),q}},[le,ce,e,f]),Ne=N.useCallback(async I=>{const O=le();if(O===null)throw new on;const $=await e.getFileInfo(I,t);if(!ce(O))throw new on;return $},[le,ce,t,e]),be=N.useCallback(async(I,O)=>{const $=le();if($!==null)try{const{name:q,contentBase64:fe,mimeType:Ie}=await e.readFile(I,t,(_t,Vs)=>{ce($)&&O?.(_t,Vs)});if(!ce($))return;const de=atob(fe),ae=new Uint8Array(de.length);for(let _t=0;_t{const I=le();if(I===null)return null;const O=++Ae.current;try{const $=await e.getModelCatalog(t);if(O!==Ae.current||!ce(I))return null;if(T($),!Ze.current){const q=Ux(qx(),$),fe=ut($.session_model_id,$),Ie=q.modelId||fe;if(q.modelId&&q.modelId!==fe){const de=$.reasoning_preset_selection_supported===!0?await e.setSessionModelSelection(t,q.modelId,null):{model_id:await e.setSessionModel(t,q.modelId),reasoning_preset:null};if(O!==Ae.current||!ce(I))return null;const ae=ut(de.model_id,$);A(ae),T(X=>X&&{...X,session_model_id:ae,session_reasoning_preset:de.reasoning_preset}),q.fallbackApplied&&ni(ae)}else A(Ie),q.fallbackApplied&&ni(Ie);Ze.current=!0}return $}catch($){return O===Ae.current&&ce(I)&&Je($,f),null}},[le,ce,t,e,f]),Nn=N.useCallback(async I=>{if(E||pe||P)return;const O=le();if(O!==null){R(!0);try{const $=m?.reasoning_preset_selection_supported===!0?await e.setSessionModelSelection(t,I,null):{model_id:await e.setSessionModel(t,I),reasoning_preset:null};if(!ce(O))return;const q=ut($.model_id,m);A(q),T(fe=>fe&&{...fe,session_model_id:q,session_reasoning_preset:$.reasoning_preset}),ni(q)}catch($){Je($,f)}finally{ce(O)&&R(!1)}}},[le,P,ce,pe,m,E,t,e,f]),tn=N.useCallback(async I=>{if(E||pe||P||m?.reasoning_preset_selection_supported!==!0)return;const O=le();if(O!==null){R(!0);try{const $=await e.setSessionModelSelection(t,j,I);if(!ce(O))return;const q=ut($.model_id,m);A(q),T(fe=>fe&&{...fe,session_model_id:q,session_reasoning_preset:$.reasoning_preset})}catch($){Je($,f)}finally{ce(O)&&R(!1)}}},[le,P,ce,pe,m,E,j,t,e,f]);N.useEffect(()=>{if(!pe)return;const I=setInterval(()=>ze(Date.now()),500);return()=>clearInterval(I)},[pe]),N.useEffect(()=>{if(!c)return;const I=setTimeout(()=>f(null),5e3);return()=>clearTimeout(I)},[c,f]),N.useEffect(()=>{if(!Qe)return;const I=setTimeout(()=>Ue(null),3200);return()=>clearTimeout(I)},[Qe]);const ht=N.useCallback(async I=>{if(I&&(_e.current||!Ce.current))return;const O=le();if(O===null)return;const $=++Z.current;try{_e.current=!0,te(!0);const q=await e.getSessionMessages(t,50,I);if($!==Z.current||!ce(O))return;if(I){const fe=a(t);l(t,[...q.messages,...fe])}else l(t,q.messages);we(q.has_more),Ce.current=q.has_more}catch(q){$===Z.current&&ce(O)&&Je(q,f)}finally{$===Z.current&&ce(O)&&(_e.current=!1,te(!1))}},[le,a,ce,t,e,f,l]),gt=()=>{ke.current&&(clearTimeout(ke.current),ke.current=void 0)},mt=N.useCallback((I,O)=>{V||(gt(),Te.current={x:O.touches[0].clientX,y:O.touches[0].clientY},ke.current=setTimeout(()=>{L(I),ke.current=void 0},500))},[V]),In=N.useCallback(I=>{const O=Math.abs(I.touches[0].clientX-Te.current.x),$=Math.abs(I.touches[0].clientY-Te.current.y);(O>10||$>10)&>()},[]),wt=N.useCallback(()=>{gt()},[]),Dt=N.useCallback(I=>{ve.current&&clearTimeout(ve.current),B(I),ve.current=setTimeout(()=>B(null),2e3)},[]),Rs=N.useCallback(async()=>{if(!se)return;const I=Jr(se.content);try{await Ss(I),Dt(o("chat.messageCopied"))}catch{Dt(o("chat.copyFailed"))}L(null)},[se,Dt,o]),Os=N.useCallback(async()=>{if(!se||se.role!=="user")return;const I=le();if(I===null)return;const O=Jr(se.content);if(!O)return;L(null);const $=se.images?.length?se.images.map((q,fe)=>{const Ie=q.data_url.split(";")[0]?.replace("data:","")||"image/png";return{id:`mobile_resend_${Date.now()}_${fe}`,data_url:q.data_url,mime_type:Ie,metadata:{name:q.name,source:"remote"}}}):void 0;try{if(await e.sendMessage(t,O,"agentic",$),!ce(I))return;b.current?.nudge()}catch(q){Je(q,f)}},[le,ce,se,t,e,f]),Ds=N.useCallback(async()=>{if(se){re(!0);try{Ft.getState().deleteMessage(t,se.id),Dt(o("chat.messageDeleted"))}finally{re(!1),L(null)}}},[se,t,Dt,o]);N.useEffect(()=>()=>{gt(),ve.current&&clearTimeout(ve.current)},[]);const St=N.useRef(!0),yt=N.useRef(!1),jn=N.useRef(!1),Ms=80,Fs=N.useCallback(()=>{const I=Me.current;if(!I)return;const $=I.scrollHeight-I.scrollTop-I.clientHeight0&&ht(q[0].id)}},[xe,ee,a,t,ht]),zs=N.useCallback(()=>{yt.current=!0,St.current=!0,He(!1),jn.current=!1,Xe.current?.scrollIntoView({behavior:"smooth"})},[]),Mt=N.useRef(!1),nn=N.useRef(!1),rn=N.useRef(0);N.useEffect(()=>{Ze.current=!1,Ce.current=!0,_e.current=!1,we(!0),te(!1),T(null),A("primary")},[t]),N.useEffect(()=>{Mt.current=!1,nn.current=!1;const I=++rn.current;let O=!1;const $=le();if($===null)return;const q=()=>!O&&rn.current===I&&ce($);return Promise.all([ht(),lt()]).then(([fe,Ie])=>{if(!q())return;const de=Ft.getState().getMessages(t).length;nn.current=!0;const ae=new Zs(e,t,X=>{q()&&(X.message_snapshot?l(t,X.message_snapshot):X.new_messages&&X.new_messages.length>0&&s(t,X.new_messages),X.total_msg_count!=null&&Ft.getState().getMessages(t).length!==X.total_msg_count&&e.getSessionMessages(t,200).then(nt=>{q()&&Ft.getState().setMessages(t,nt.messages)}).catch(()=>{}),X.title&&(C(X.title),g(t,X.title)),X.model_catalog&&(T(X.model_catalog),A(ut(X.model_catalog.session_model_id,X.model_catalog))),p(X.active_turn??null))},Ie?.version||0);ae.start(de),b.current=ae}),()=>{O=!0,rn.current===I&&(rn.current+=1),b.current?.stop(),b.current=null,p(null)}},[s,le,ce,ht,lt,t,e,p,l,g]);const an=N.useRef(0);N.useLayoutEffect(()=>{if(!nn.current||x.length===0)return;nn.current=!1;const I=Me.current;I&&(I.scrollTop=I.scrollHeight),Mt.current=!0,an.current=x.length},[x]),N.useEffect(()=>{if(Mt.current&&x.length!==an.current){const I=x.length>an.current;an.current=x.length,I&&!ee&&St.current&&(yt.current=!0,Xe.current?.scrollIntoView({behavior:"smooth"}))}},[x.length,ee]),N.useEffect(()=>{!Mt.current||!pe||St.current&&(yt.current=!0,Xe.current?.scrollIntoView({behavior:"auto"}))},[u,pe]),N.useEffect(()=>{G&&(yt.current=!0,St.current=!0,Xe.current?.scrollIntoView({behavior:"smooth"}))},[G]),N.useEffect(()=>{if(!Mt.current||!pe)return;const I=Me.current;if(!I)return;const O=setInterval(()=>{if(!St.current)return;const $=I.scrollHeight-I.scrollTop-I.clientHeight;$>10&&$<400&&(yt.current=!0,I.scrollTo({top:I.scrollHeight,behavior:"smooth"}))},300);return()=>clearInterval(O)},[pe]);const Rn=N.useCallback(async()=>{const I=v.trim(),O=M;if(!I&&O.length===0||P)return;const $=le();if($===null)return;const q=pe;y(""),H([]),q||ie(!1);const fe=O.length>0,Ie=fe?O.map((de,ae)=>{const X=de.dataUrl.split(";")[0]?.replace("data:","")||"image/png";return{id:`mobile_img_${Date.now()}_${ae}`,data_url:de.dataUrl,mime_type:X,metadata:{name:de.name,source:"remote"}}}):void 0;fe&&(J({id:`opt_${Date.now()}`,text:I||"",images:O.map(de=>({name:de.name,data_url:de.dataUrl}))}),z(!0));try{if(await e.sendMessage(t,I||o("chat.imageAttachmentFallback"),"agentic",Ie),!ce($))return;b.current?.nudge(),q&&Ue(o("chat.messageQueued"))}catch(de){Je(de,f)}finally{ce($)&&(z(!1),J(null))}},[le,P,v,ce,pe,M,t,e,f,o]),Ps=N.useCallback(()=>{K.current?.click()},[]),Bs=N.useCallback(async I=>{const O=I.target.files;if(!O)return;const $=5,q=$-M.length,fe=Array.from(O).slice(0,q),{compressImageFile:Ie}=await Xs(async()=>{const{compressImageFile:de}=await import("./imageCompressor-Cy77l5Xt.js");return{compressImageFile:de}},[],import.meta.url);for(const de of fe)try{const ae=await Ie(de);H(X=>X.length>=$?X:[...X,{name:ae.name,dataUrl:ae.dataUrl}])}catch{const ae=new FileReader;ae.onload=()=>{const X=ae.result;H(ue=>ue.length>=$?ue:[...ue,{name:de.name,dataUrl:X}])},ae.readAsDataURL(de)}I.target.value=""},[M.length]),$s=N.useCallback(I=>{H(O=>O.filter(($,q)=>q!==I))},[]),Wi=N.useCallback(()=>{ie(!0),requestAnimationFrame(()=>w.current?.focus())},[]);N.useEffect(()=>{i&&requestAnimationFrame(()=>w.current?.focus())},[i]),N.useEffect(()=>{if(!U)return;const I=O=>{Y.current&&!Y.current.contains(O.target)&&!v.trim()&&M.length===0&&ie(!1)};return document.addEventListener("mousedown",I),()=>document.removeEventListener("mousedown",I)},[U,v,M.length]);const On=N.useRef(!1),qs=N.useCallback(()=>{On.current=!0},[]),Us=N.useCallback(()=>{setTimeout(()=>{On.current=!1},0)},[]),Hs=I=>{if(I.key==="Enter"&&!I.shiftKey){if(I.nativeEvent.isComposing||On.current)return;I.preventDefault(),Rn()}},Ws=async()=>{if(le()!==null)try{await e.cancelTask(t,u?.turn_id)}catch{}},Vi=d?.project_name||d?.path?.split("/").pop()||"",Dn=d?.git_branch,Gi=_||n||o("chat.session");return h.jsxs("div",{className:"chat-page",children:[h.jsx("div",{className:"chat-page__header",children:h.jsxs("div",{className:"chat-page__header-row",children:[h.jsx("button",{className:"chat-page__back",onClick:r,"aria-label":o("common.back"),children:h.jsx("svg",{width:"18",height:"18",viewBox:"0 0 20 20",fill:"none",children:h.jsx("path",{d:"M12 4L6 10L12 16",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsxs("div",{className:"chat-page__header-center",children:[h.jsx("span",{className:"chat-page__title",title:Gi,children:Gi}),Vi&&h.jsxs("div",{className:"chat-page__header-workspace",title:d?.path,children:[h.jsx("span",{className:"chat-page__workspace-name",children:Vi}),Dn&&h.jsxs("span",{className:"chat-page__workspace-branch",title:Dn,children:[h.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("line",{x1:"6",x2:"6",y1:"3",y2:"15"}),h.jsx("circle",{cx:"18",cy:"6",r:"3"}),h.jsx("circle",{cx:"6",cy:"18",r:"3"}),h.jsx("path",{d:"M18 9a9 9 0 0 1-9 9"})]}),wx(Dn,28)]})]})]}),h.jsx("div",{className:"chat-page__header-right",children:h.jsx("button",{className:"chat-page__theme-btn",onClick:S,"aria-label":o("common.toggleTheme"),children:h.jsx(zx,{isDark:k})})})]})}),h.jsxs("div",{className:"chat-page__messages",ref:Me,onScroll:Fs,children:[ee&&h.jsx("div",{className:"chat-page__load-more-indicator",children:o("chat.loadingOlderMessages")}),(()=>{const I=x.reduceRight((O,$,q)=>O<0&&$.role==="user"?q:O,-1);return x.map((O,$)=>{if(O.role==="system"||O.role==="tool")return null;if(O.role==="user"){const ae=Jr(O.content);return h.jsx("div",{className:`chat-msg chat-msg--user${se?.id===O.id?" chat-msg--menu-active":""}`,onTouchStart:X=>mt(O,X),onTouchMove:In,onTouchEnd:wt,onTouchCancel:wt,onContextMenu:X=>{X.preventDefault(),L(O)},children:h.jsxs("div",{className:"chat-msg__user-card",children:[h.jsx("div",{className:"chat-msg__user-avatar",children:"U"}),h.jsxs("div",{className:"chat-msg__user-content",children:[ae,O.images&&O.images.length>0&&h.jsx("div",{className:"chat-msg__user-images",children:O.images.map((X,ue)=>h.jsx("img",{src:X.data_url,alt:X.name,className:"chat-msg__user-image"},ue))})]})]})},O.id)}const q=O.items&&O.items.length>0,fe=O.thinking||O.tools&&O.tools.length>0||O.content;if(!q&&!fe)return null;const Ie=$mt(O,ae),onTouchMove:In,onTouchEnd:wt,onTouchCancel:wt,onContextMenu:ae=>{ae.preventDefault(),L(O)},children:h.jsxs("button",{className:"chat-msg__response-toggle",onClick:()=>Fe(ae=>{const X=new Set(ae);return X.add(O.id),X}),children:[h.jsx("span",{className:"chat-msg__response-chevron",children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M6 4L10 8L6 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsx("span",{className:"chat-msg__response-label",children:o("chat.showResponse")})]})},O.id):h.jsxs("div",{className:`chat-msg chat-msg--assistant${se?.id===O.id?" chat-msg--menu-active":""}`,onTouchStart:ae=>mt(O,ae),onTouchMove:In,onTouchEnd:wt,onTouchCancel:wt,onContextMenu:ae=>{ae.preventDefault(),L(O)},children:[Ie&&de&&h.jsxs("button",{className:"chat-msg__response-toggle",onClick:()=>Fe(ae=>{const X=new Set(ae);return X.delete(O.id),X}),children:[h.jsx("span",{className:"chat-msg__response-chevron is-open",children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M6 4L10 8L6 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsx("span",{className:"chat-msg__response-label",children:o("chat.hideResponse")})]}),q?Vo(O.items,Se,void 0,Le,be,Ne):h.jsxs(h.Fragment,{children:[O.thinking&&h.jsx(xi,{thinking:O.thinking}),O.tools&&O.tools.length>0&&h.jsx(ki,{tools:O.tools,now:Se}),O.content&&h.jsx("div",{className:"chat-msg__assistant-content",children:h.jsx(Kt,{content:O.content,onFileDownload:be,onGetFileInfo:Ne})})]})]},O.id)})})(),u&&(()=>{const I=u,O=I.status==="active";if(I.items&&I.items.length>0)return h.jsxs("div",{className:"chat-msg chat-msg--assistant",children:[O?Fx(I.items,Se,e,f,()=>le()!==null,Le,be,Ne):Vo(I.items,Se,void 0,void 0,be,Ne),O&&!I.thinking&&!I.text&&I.tools.length===0&&h.jsx("div",{className:"chat-msg__assistant-content",children:h.jsx(ti,{})})]});const $=I.tools.filter(ue=>ue.name==="Task"),q=$.some(ue=>ue.status==="running"),fe=I.tools.filter(ue=>ue.name==="AskUserQuestion"&&ue.status==="running"&&ue.tool_input),Ie=new Set(fe.map(ue=>ue.id)),de=I.tools.filter(ue=>ue.name!=="Task"&&!Ie.has(ue.id)),ae=q?[...I.thinking?[{type:"thinking",content:I.thinking}]:[],...de.map(ue=>({type:"tool",tool:ue}))]:[],X=ue=>{le()!==null&&e.cancelTool(ue,o("common.cancel")).catch(nt=>{Je(nt,f)})};return h.jsxs("div",{className:"chat-msg chat-msg--assistant",children:[!q&&(I.thinking||O)&&h.jsx(xi,{thinking:I.thinking,streaming:O,isLastItem:O}),$.map(ue=>h.jsx(_s,{tool:ue,now:Se,subItems:ue.status==="running"?ae:void 0,onCancelTool:X},ue.id)),!q&&de.length>0&&h.jsx(ki,{tools:de,now:Se,onCancelTool:X}),O&&fe.map(ue=>h.jsx(As,{tool:ue,onAnswer:Le},ue.id)),!q&&I.text?h.jsx("div",{className:"chat-msg__assistant-content",children:O?h.jsx(Ts,{content:I.text,onFileDownload:be,onGetFileInfo:Ne}):h.jsx(Kt,{content:I.text,onFileDownload:be,onGetFileInfo:Ne})}):O&&!I.thinking&&I.tools.length===0?h.jsx("div",{className:"chat-msg__assistant-content",children:h.jsx(ti,{})}):null]})})(),G&&h.jsx("div",{className:"chat-msg chat-msg--user",children:h.jsxs("div",{className:"chat-msg__user-card",children:[h.jsx("div",{className:"chat-msg__user-avatar",children:"U"}),h.jsxs("div",{className:"chat-msg__user-content",children:[G.text,G.images.length>0&&h.jsx("div",{className:"chat-msg__user-images",children:G.images.map((I,O)=>h.jsx("img",{src:I.data_url,alt:I.name,className:"chat-msg__user-image"},O))})]})]})}),P&&h.jsx("div",{className:"chat-msg chat-msg--assistant",children:h.jsx("div",{className:"chat-msg__assistant-card",children:h.jsxs("div",{className:"chat-msg__image-analyzing",children:[h.jsx("div",{className:"chat-msg__image-analyzing-icon",children:h.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("circle",{cx:"12",cy:"12",r:"3"}),h.jsx("path",{d:"M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"})]})}),h.jsx("span",{children:o("chat.analyzingImage")}),h.jsx(ti,{})]})})}),h.jsx("div",{ref:Xe})]}),ft&&h.jsx("button",{type:"button",className:"chat-page__scroll-to-bottom",onClick:zs,"aria-label":o("chat.scrollToBottom"),children:h.jsx("svg",{"aria-hidden":"true",focusable:"false",width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("polyline",{points:"6 9 12 15 18 9"})})}),se&&h.jsx("div",{className:"chat-msg__menu-overlay",onClick:()=>L(null),children:h.jsxs("div",{className:"chat-msg__menu-sheet",onClick:I=>I.stopPropagation(),children:[h.jsx("div",{className:"chat-msg__menu-handle"}),h.jsxs("div",{className:"chat-msg__menu-actions",children:[h.jsxs("button",{className:"chat-msg__menu-btn",onClick:Rs,children:[h.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),h.jsx("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]}),h.jsx("span",{children:o("chat.copyMessage")})]}),se.role==="user"&&h.jsxs("button",{className:"chat-msg__menu-btn",onClick:Os,children:[h.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("polyline",{points:"23 4 23 10 17 10"}),h.jsx("path",{d:"M20.49 15a9 9 0 1 1-2.12-9.36L23 10"})]}),h.jsx("span",{children:o("chat.resendMessage")})]}),h.jsxs("button",{className:"chat-msg__menu-btn chat-msg__menu-btn--danger",onClick:Ds,disabled:V,children:[h.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("polyline",{points:"3 6 5 6 21 6"}),h.jsx("path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"})]}),h.jsx("span",{children:V?"...":o("chat.deleteMessage")})]})]}),h.jsx("button",{className:"chat-msg__menu-cancel",onClick:()=>L(null),children:o("common.cancel")})]})}),D&&h.jsx("div",{className:"chat-page__toast",role:"alert","aria-live":"assertive",children:D}),h.jsx("input",{ref:K,type:"file",accept:"image/png,image/jpeg,image/jpg,image/gif,image/webp",multiple:!0,style:{display:"none"},onChange:Bs}),h.jsx("div",{className:`chat-page__input-wrap ${U?"is-expanded":""}`,ref:Y,children:h.jsxs("div",{className:"chat-page__input-box",onClick:U?void 0:Wi,children:[h.jsx("div",{className:"chat-page__input-area",children:U?h.jsx("textarea",{ref:w,className:"chat-page__input",placeholder:o("chat.inputPlaceholder"),value:v,onChange:I=>y(I.target.value),onKeyDown:Hs,onCompositionStart:qs,onCompositionEnd:Us,rows:1,disabled:P}):h.jsx("span",{className:"chat-page__input-placeholder",children:o(P?"chat.imageAnalyzingPlaceholder":pe?"chat.collapsedStreamingPlaceholder":"chat.collapsedInputPlaceholder")})}),h.jsxs("div",{className:"chat-page__input-actions",children:[h.jsxs("div",{className:"chat-page__input-actions-left",children:[U&&h.jsxs(h.Fragment,{children:[h.jsx(Wx,{catalog:m,selectedModelId:j,disabled:P||pe||E,onSelect:Nn}),h.jsx(Vx,{catalog:m,selectedModelId:j,disabled:P||pe||E,onSelect:tn})]}),U&&M.length>0&&h.jsx("div",{className:"chat-page__image-preview-row",children:M.map((I,O)=>h.jsxs("div",{className:"chat-page__image-thumb",children:[h.jsx("img",{src:I.dataUrl,alt:I.name}),h.jsx("button",{className:"chat-page__image-remove",onClick:()=>$s(O),children:"×"})]},O))})]}),h.jsxs("div",{className:"chat-page__input-actions-right",children:[U&&h.jsx("button",{className:"chat-page__action-btn",onClick:Ps,disabled:P||M.length>=5,"aria-label":o("common.attachImage"),children:h.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",ry:"2"}),h.jsx("circle",{cx:"9",cy:"9",r:"2"}),h.jsx("path",{d:"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"})]})}),P?h.jsx("button",{className:"chat-page__send-btn is-stop","aria-label":o("common.stop"),disabled:!0,children:h.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",style:{animation:"analyzeSpin 2s linear infinite"},children:[h.jsx("circle",{cx:"12",cy:"12",r:"3"}),h.jsx("path",{d:"M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2"})]})}):pe?h.jsxs("div",{className:"chat-page__stream-actions",children:[h.jsx("button",{type:"button",className:"chat-page__send-btn is-stop",onClick:Ws,"aria-label":o("common.stop"),children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("rect",{x:"3",y:"3",width:"10",height:"10",rx:"2",fill:"currentColor"})})}),h.jsx("button",{type:"button",className:"chat-page__send-btn",onClick:U?Rn:Wi,disabled:!v.trim()&&M.length===0,"aria-label":o("common.submit"),children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 20 20",fill:"none",children:h.jsx("path",{d:"M10 3L10 17M10 3L5 8M10 3L15 8",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]}):h.jsx("button",{className:"chat-page__send-btn",onClick:U?Rn:void 0,disabled:!v.trim()&&M.length===0,children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 20 20",fill:"none",children:h.jsx("path",{d:"M10 3L10 17M10 3L5 8M10 3L15 8",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]})]})]})}),c&&h.jsx("div",{className:"chat-page__toast",onClick:()=>f(null),children:c}),Qe&&h.jsx("div",{className:"chat-page__toast chat-page__toast--info",onClick:()=>Ue(null),children:Qe})]})};export{Zx as default};
+`),c=l&&u===e.length-1;return h.jsx(xi,{thinking:p,streaming:c,isLastItem:c},`${t}-thinking-${u}`)}if(s.type==="tool"){const p=[];let c=[],f=[];const d=()=>{f.length>0&&(p.push(h.jsx(Rx,{tools:f},`${t}-read-${u}-${p.length}`)),f=[])},g=()=>{c.length>0&&(p.push(h.jsx(ki,{tools:c,now:n,onCancelTool:r},`${t}-tl-${u}-${p.length}`)),c=[])},k=()=>{d(),g()};for(const S of s.entries)S.tool?.name==="Task"?(k(),p.push(h.jsx(_s,{tool:S.tool,now:n,subItems:S.subItems,onCancelTool:r},`${t}-task-${u}-${p.length}`))):S.tool?.name==="TodoWrite"?(k(),p.push(h.jsx(Ax,{tool:S.tool},`${t}-todo-${u}-${p.length}`))):S.tool&&Ix.has(S.tool.name)?(g(),f.push(S.tool)):S.tool&&(d(),c.push(S.tool));return k(),h.jsx(it.Fragment,{children:p},`${t}-tool-${u}`)}if(s.type==="text"){const p=s.entries.map(c=>c.content||"").join("");return p?h.jsx("div",{className:"chat-msg__assistant-content",children:i?h.jsx(Ts,{content:p,onFileDownload:o,onGetFileInfo:a}):h.jsx(Kt,{content:p,onFileDownload:o,onGetFileInfo:a})},`${t}-text-${u}`):null}return null})}function Vo(e,t,n,r,i,o){const a=Ls(e),l=a.filter(c=>_n(c.tool));if(l.length===0)return It(Nt(a),"ordered",t,n,!1,i,o);const s=[],u=[];let p=!1;for(const c of a)_n(c.tool)?p=!0:p?u.push(c):s.push(c);return h.jsxs(h.Fragment,{children:[It(Nt(s),"ordered-before",t,n,!1,i,o),Ns(l,"ordered",r),It(Nt(u),"ordered-after",t,n,!1,i,o)]})}function Fx(e,t,n,r,i,o,a,l){const s=Ls(e),u=s.filter(g=>_n(g.tool)),p=g=>{i()&&n.cancelTool(g,"User cancelled").catch(k=>{Je(k,r)})};if(u.length===0)return It(Nt(s),"active",t,p,!0,a,l,!0);const c=[],f=[];let d=!1;for(const g of s)_n(g.tool)?d=!0:d?f.push(g):c.push(g);return h.jsxs(h.Fragment,{children:[It(Nt(c),"active-before",t,p,!0,a,l,!0),Ns(u,"active",o),It(Nt(f),"active-after",t,p,!0,a,l,!0)]})}const zx=({isDark:e})=>h.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:e?h.jsx("path",{d:"M8 1.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM3 8a5 5 0 0 1 5-5v10a5 5 0 0 1-5-5Z",fill:"currentColor"}):h.jsx("path",{d:"M8 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 8 1Zm0 11a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 8 12Zm7-4a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1 0-1h1A.5.5 0 0 1 15 8ZM3 8a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1 0-1h1A.5.5 0 0 1 3 8Zm9.95-3.54a.5.5 0 0 1 0 .71l-.71.7a.5.5 0 1 1-.7-.7l.7-.71a.5.5 0 0 1 .71 0ZM5.46 11.24a.5.5 0 0 1 0 .71l-.7.71a.5.5 0 0 1-.71-.71l.7-.71a.5.5 0 0 1 .71 0Zm7.08 1.42a.5.5 0 0 1-.7 0l-.71-.71a.5.5 0 0 1 .7-.7l.71.7a.5.5 0 0 1 0 .71ZM5.46 4.76a.5.5 0 0 1-.71 0l-.71-.7a.5.5 0 0 1 .71-.71l.7.7a.5.5 0 0 1 0 .71ZM8 5a3 3 0 1 1 0 6 3 3 0 0 1 0-6Z",fill:"currentColor"})}),vi=({className:e,size:t=10})=>h.jsxs("svg",{className:e,width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[h.jsx("path",{d:"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.937A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .962 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.582a.5.5 0 0 1 0 .962L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.962 0z"}),h.jsx("path",{d:"M20 3v4"}),h.jsx("path",{d:"M22 5h-4"}),h.jsx("path",{d:"M4 17v2"}),h.jsx("path",{d:"M5 18H3"})]});function Is(e){const t=e.trim();return t?t.charAt(0).toUpperCase()+t.slice(1):"Unknown"}function Px(e){const t=e.name?.trim();return t||Is(e.provider)}function Bx(e){return e?`${Math.round(e/1e3)}k`:null}function $x(e){return e.enabled&&Array.isArray(e.capabilities)&&e.capabilities.includes("text_chat")}function ut(e,t){const n=e?.trim();if(!n||n==="primary")return"primary";if(n==="fast"){const r=t?.default_models?.fast;return r&&at(r,t)?n:"primary"}return at(n,t)?n:"primary"}function qx(){return typeof window>"u"?null:window.localStorage.getItem(yi)?.trim()||null}function ni(e){if(typeof window>"u")return;const t=e.trim();if(!t){window.localStorage.removeItem(yi);return}window.localStorage.setItem(yi,t)}function Ux(e,t){const n=e?.trim();if(!n)return{modelId:null,fallbackApplied:!1};const r=ut(n,t);return{modelId:r,fallbackApplied:r!==n}}function at(e,t){return t&&t.models.find(n=>n.id===e)||null}function js(e,t){const n=ut(e,t);return n==="primary"?at(t?.default_models?.primary||"",t):n==="fast"?at(t?.default_models?.fast||"",t)||at(t?.default_models?.primary||"",t):at(n,t)}function Vt(e){if(!e)return null;const t=[Px(e)],n=Bx(e.context_window);return n&&t.push(n),t.join(" · ")}function gn(e){return e&&(e.model_name||e.name)||""}function Go(e,t){if(e?.reasoning?.status!=="known")return;const n=t?.session_reasoning_preset?.trim();if(n)return e.reasoning.presets?.find(r=>r.id===n)?.label||n}function Hx(e,t,n){if(e==="primary"||e==="fast"){const i=js(e,t);return{label:n(e==="primary"?"chat.modelPrimary":"chat.modelFast"),meta:Vt(i)||n(e==="primary"?"chat.modelPrimaryDesc":"chat.modelFastDesc"),enableThinking:i?.reasoning?.status==="known",reasoningEffort:Go(i,t)}}const r=at(e,t);return r?{label:gn(r),meta:Vt(r),enableThinking:r.reasoning?.status==="known",reasoningEffort:Go(r,t)}:{label:n("chat.modelPrimary"),meta:n("chat.modelPrimaryDesc"),enableThinking:!1}}const Wx=({catalog:e,selectedModelId:t,disabled:n,onSelect:r})=>{const{t:i}=Ye(),[o,a]=N.useState(!1),l=N.useRef(null),s=N.useMemo(()=>ut(t,e),[e,t]),u=N.useMemo(()=>(e?.models||[]).filter($x),[e]),p=N.useMemo(()=>at(e?.default_models?.primary||"",e),[e]),c=N.useMemo(()=>at(e?.default_models?.fast||"",e),[e]),f=N.useMemo(()=>Hx(s,e,i),[e,s,i]);if(N.useEffect(()=>{if(!o)return;const g=k=>{l.current&&!l.current.contains(k.target)&&a(!1)};return document.addEventListener("mousedown",g),()=>document.removeEventListener("mousedown",g)},[o]),!e)return null;const d=async g=>{await r(g),a(!1)};return h.jsxs("div",{className:"chat-model-selector",ref:l,children:[h.jsxs("button",{className:`chat-model-selector__trigger${o?" chat-model-selector__trigger--open":""}`,type:"button",onClick:()=>a(g=>!g),disabled:n,"aria-label":i("chat.modelSelection"),children:[h.jsx("span",{className:"chat-model-selector__icon","aria-hidden":"true",children:h.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",children:[h.jsx("rect",{x:"4",y:"4",width:"6",height:"6",rx:"1.5",stroke:"currentColor",strokeWidth:"1.7"}),h.jsx("rect",{x:"14",y:"4",width:"6",height:"6",rx:"1.5",stroke:"currentColor",strokeWidth:"1.7"}),h.jsx("rect",{x:"9",y:"14",width:"6",height:"6",rx:"1.5",stroke:"currentColor",strokeWidth:"1.7"}),h.jsx("path",{d:"M10 7h4M12 10v4",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round"})]})}),h.jsxs("span",{className:"chat-model-selector__name",children:[h.jsx("span",{className:"chat-model-selector__name-text",children:f.label}),f.enableThinking&&h.jsx(vi,{className:"chat-model-selector__thinking",size:9})]}),f.reasoningEffort&&h.jsx("span",{className:"chat-model-selector__effort",children:f.reasoningEffort}),h.jsx("span",{className:"chat-model-selector__chevron","aria-hidden":"true",children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M4 6L8 10L12 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]}),o&&h.jsxs("div",{className:"chat-model-selector__dropdown",children:[h.jsx("div",{className:"chat-model-selector__header",children:i("chat.modelSelection")}),h.jsx("button",{className:`chat-model-selector__option${s==="primary"?" is-selected":""}`,type:"button",onClick:()=>{d("primary")},children:h.jsxs("span",{className:"chat-model-selector__option-main",children:[h.jsx("span",{className:"chat-model-selector__option-name",children:i("chat.modelPrimary")}),h.jsxs("span",{className:"chat-model-selector__option-meta chat-model-selector__option-meta--stacked",children:[h.jsx("span",{className:"chat-model-selector__option-meta-line",children:gn(p)||i("chat.modelPrimary")}),h.jsx("span",{className:"chat-model-selector__option-meta-line",children:Vt(p)||i("chat.modelPrimaryDesc")})]})]})}),h.jsx("button",{className:`chat-model-selector__option${s==="fast"?" is-selected":""}`,type:"button",onClick:()=>{d("fast")},children:h.jsxs("span",{className:"chat-model-selector__option-main",children:[h.jsx("span",{className:"chat-model-selector__option-name",children:i("chat.modelFast")}),h.jsxs("span",{className:"chat-model-selector__option-meta chat-model-selector__option-meta--stacked",children:[h.jsx("span",{className:"chat-model-selector__option-meta-line",children:gn(c)||i("chat.modelFast")}),h.jsx("span",{className:"chat-model-selector__option-meta-line",children:Vt(c)||i("chat.modelFastDesc")})]})]})}),h.jsx("div",{className:"chat-model-selector__divider"}),h.jsx("div",{className:"chat-model-selector__list",children:u.map(g=>{const k=s===g.id;return h.jsx("button",{className:`chat-model-selector__option${k?" is-selected":""}`,type:"button",onClick:()=>{d(g.id)},children:h.jsxs("span",{className:"chat-model-selector__option-main",children:[h.jsxs("span",{className:"chat-model-selector__option-name",children:[h.jsx("span",{className:"chat-model-selector__option-name-text",children:gn(g)}),g.reasoning?.status==="known"&&h.jsx(vi,{className:"chat-model-selector__option-thinking",size:10})]}),h.jsx("span",{className:"chat-model-selector__option-meta",children:Vt(g)||Is(g.provider)})]})},g.id)})})]})]})},Vx=({catalog:e,selectedModelId:t,disabled:n,onSelect:r})=>{const{t:i}=Ye(),[o,a]=N.useState(!1),l=N.useRef(null),s=N.useMemo(()=>js(t,e),[e,t]),u=N.useMemo(()=>[...s?.reasoning?.presets||[]].sort((k,S)=>k.order-S.order),[s]),p=e?.session_reasoning_preset?.trim()||null,c=p?u.find(k=>k.id===p)?.label||p:i("chat.reasoningAuto"),f=e?.reasoning_preset_selection_supported===!0,d=n||!f;if(N.useEffect(()=>{if(!o)return;const k=S=>{l.current&&!l.current.contains(S.target)&&a(!1)};return document.addEventListener("mousedown",k),()=>document.removeEventListener("mousedown",k)},[o]),s?.reasoning?.status!=="known"||u.length===0)return null;const g=async k=>{await r(k),a(!1)};return h.jsxs("div",{className:"chat-model-selector chat-reasoning-selector",ref:l,children:[h.jsxs("button",{className:`chat-model-selector__trigger chat-reasoning-selector__trigger${o?" chat-model-selector__trigger--open":""}`,type:"button",onClick:()=>a(k=>!k),disabled:d,"aria-label":i("chat.reasoningSelection"),children:[h.jsx(vi,{className:"chat-model-selector__thinking",size:10}),h.jsx("span",{className:"chat-model-selector__name chat-reasoning-selector__name",children:h.jsx("span",{className:"chat-model-selector__name-text",children:c})}),h.jsx("span",{className:"chat-model-selector__chevron","aria-hidden":"true",children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M4 6L8 10L12 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]}),o&&f&&h.jsxs("div",{className:"chat-model-selector__dropdown chat-reasoning-selector__dropdown",children:[h.jsx("div",{className:"chat-model-selector__header",children:i("chat.reasoningSelection")}),h.jsxs("div",{className:"chat-model-selector__list",children:[h.jsx("button",{className:`chat-model-selector__option${p===null?" is-selected":""}`,type:"button",onClick:()=>{g(null)},children:h.jsx("span",{className:"chat-model-selector__option-name",children:i("chat.reasoningAuto")})}),u.map(k=>h.jsx("button",{className:`chat-model-selector__option${p===k.id?" is-selected":""}`,type:"button",onClick:()=>{g(k.id)},children:h.jsx("span",{className:"chat-model-selector__option-name",children:k.label})},k.id))]})]})]})},Zx=({sessionMgr:e,sessionId:t,sessionName:n,onBack:r,autoFocus:i})=>{const{t:o}=Ye(),{getMessages:a,setMessages:l,appendNewMessages:s,activeTurn:u,setActiveTurn:p,error:c,setError:f,currentWorkspace:d,updateSessionName:g}=Ft(),{isDark:k,toggleTheme:S}=Zo(),x=a(t),[v,b]=N.useState(""),[_,C]=N.useState(n),[m,T]=N.useState(null),[j,A]=N.useState("primary"),[E,R]=N.useState(!1),[M,H]=N.useState([]),[P,z]=N.useState(!1),[G,J]=N.useState(null),[U,ie]=N.useState(!!i),w=N.useRef(null),K=N.useRef(null),Y=N.useRef(null),y=N.useRef(null),Z=N.useRef(0),[ee,te]=N.useState(!1),[xe,we]=N.useState(!0),_e=N.useRef(!1),Ce=N.useRef(!0),be=Gs(e),qe=N.useRef({sessionMgr:e,sessionId:t,epoch:be,active:!0});(qe.current.sessionMgr!==e||qe.current.sessionId!==t||qe.current.epoch!==be)&&(qe.current={sessionMgr:e,sessionId:t,epoch:be,active:!0});const le=N.useCallback(()=>{const I=qe.current;return!I.active||I.sessionMgr!==e||I.sessionId!==t||I.epoch!==e.controlTargetEpoch?null:I.epoch},[be,t,e]),ce=N.useCallback(I=>{const O=qe.current;return I!==null&&O.active&&O.sessionMgr===e&&O.sessionId===t&&O.epoch===I&&e.controlTargetEpoch===I},[be,t,e]),Ze=N.useRef(!1),Ae=N.useRef(0),Xe=N.useRef(null),Me=N.useRef(null),[dt,Fe]=N.useState(new Set),[Qe,Ue]=N.useState(null),[ft,He]=N.useState(!1),[se,L]=N.useState(null),[D,B]=N.useState(null),[V,re]=N.useState(!1),ke=N.useRef(),Te=N.useRef({x:0,y:0}),ve=N.useRef(),je=N.useRef({sessionMgr:e,sessionId:t,epoch:be});N.useLayoutEffect(()=>{const I=je.current,O=I.sessionMgr!==e||I.sessionId!==t||I.epoch!==be,$=qe.current;return $.active=$.sessionMgr===e&&$.sessionId===t&&$.epoch===be&&e.controlTargetEpoch===be,O&&(Z.current+=1,Ae.current+=1,_e.current=!1,Ce.current=!0,te(!1),we(!0),R(!1),z(!1),J(null),Ze.current=!1,T(null),A("primary"),l(t,[]),L(null),re(!1),B(null),Ue(null),Fe(new Set),He(!1),p(null),ke.current&&(clearTimeout(ke.current),ke.current=void 0),ve.current&&(clearTimeout(ve.current),ve.current=void 0),y.current?.stop(),y.current=null),je.current={sessionMgr:e,sessionId:t,epoch:be},()=>{$.active=!1,Z.current+=1,Ae.current+=1,y.current?.stop()}},[be,t,e,p,l]);const pe=u!=null&&u.status==="active",[Se,ze]=N.useState(()=>Date.now()),Le=N.useCallback(async(I,O)=>{const $=le();if($===null)throw new on;try{if(await e.answerQuestion(I,O),!ce($))throw new on}catch(q){throw Je(q,f),q}},[le,ce,e,f]),Ne=N.useCallback(async I=>{const O=le();if(O===null)throw new on;const $=await e.getFileInfo(I,t);if(!ce(O))throw new on;return $},[le,ce,t,e]),ye=N.useCallback(async(I,O)=>{const $=le();if($!==null)try{const{name:q,contentBase64:fe,mimeType:Ie}=await e.readFile(I,t,(_t,Vs)=>{ce($)&&O?.(_t,Vs)});if(!ce($))return;const de=atob(fe),ae=new Uint8Array(de.length);for(let _t=0;_t{const I=le();if(I===null)return null;const O=++Ae.current;try{const $=await e.getModelCatalog(t);if(O!==Ae.current||!ce(I))return null;if(T($),!Ze.current){const q=Ux(qx(),$),fe=ut($.session_model_id,$),Ie=q.modelId||fe;if(q.modelId&&q.modelId!==fe){const de=$.reasoning_preset_selection_supported===!0?await e.setSessionModelSelection(t,q.modelId,null):{model_id:await e.setSessionModel(t,q.modelId),reasoning_preset:null};if(O!==Ae.current||!ce(I))return null;const ae=ut(de.model_id,$);A(ae),T(X=>X&&{...X,session_model_id:ae,session_reasoning_preset:de.reasoning_preset}),q.fallbackApplied&&ni(ae)}else A(Ie),q.fallbackApplied&&ni(Ie);Ze.current=!0}return $}catch($){return O===Ae.current&&ce(I)&&Je($,f),null}},[le,ce,t,e,f]),Nn=N.useCallback(async I=>{if(E||pe||P)return;const O=le();if(O!==null){R(!0);try{const $=m?.reasoning_preset_selection_supported===!0?await e.setSessionModelSelection(t,I,null):{model_id:await e.setSessionModel(t,I),reasoning_preset:null};if(!ce(O))return;const q=ut($.model_id,m);A(q),T(fe=>fe&&{...fe,session_model_id:q,session_reasoning_preset:$.reasoning_preset}),ni(q)}catch($){Je($,f)}finally{ce(O)&&R(!1)}}},[le,P,ce,pe,m,E,t,e,f]),tn=N.useCallback(async I=>{if(E||pe||P||m?.reasoning_preset_selection_supported!==!0)return;const O=le();if(O!==null){R(!0);try{const $=await e.setSessionModelSelection(t,j,I);if(!ce(O))return;const q=ut($.model_id,m);A(q),T(fe=>fe&&{...fe,session_model_id:q,session_reasoning_preset:$.reasoning_preset})}catch($){Je($,f)}finally{ce(O)&&R(!1)}}},[le,P,ce,pe,m,E,j,t,e,f]);N.useEffect(()=>{if(!pe)return;const I=setInterval(()=>ze(Date.now()),500);return()=>clearInterval(I)},[pe]),N.useEffect(()=>{if(!c)return;const I=setTimeout(()=>f(null),5e3);return()=>clearTimeout(I)},[c,f]),N.useEffect(()=>{if(!Qe)return;const I=setTimeout(()=>Ue(null),3200);return()=>clearTimeout(I)},[Qe]);const ht=N.useCallback(async I=>{if(I&&(_e.current||!Ce.current))return;const O=le();if(O===null)return;const $=++Z.current;try{_e.current=!0,te(!0);const q=await e.getSessionMessages(t,50,I);if($!==Z.current||!ce(O))return;if(I){const fe=a(t);l(t,[...q.messages,...fe])}else l(t,q.messages);we(q.has_more),Ce.current=q.has_more}catch(q){$===Z.current&&ce(O)&&Je(q,f)}finally{$===Z.current&&ce(O)&&(_e.current=!1,te(!1))}},[le,a,ce,t,e,f,l]),gt=()=>{ke.current&&(clearTimeout(ke.current),ke.current=void 0)},mt=N.useCallback((I,O)=>{V||(gt(),Te.current={x:O.touches[0].clientX,y:O.touches[0].clientY},ke.current=setTimeout(()=>{L(I),ke.current=void 0},500))},[V]),In=N.useCallback(I=>{const O=Math.abs(I.touches[0].clientX-Te.current.x),$=Math.abs(I.touches[0].clientY-Te.current.y);(O>10||$>10)&>()},[]),wt=N.useCallback(()=>{gt()},[]),Dt=N.useCallback(I=>{ve.current&&clearTimeout(ve.current),B(I),ve.current=setTimeout(()=>B(null),2e3)},[]),Rs=N.useCallback(async()=>{if(!se)return;const I=Jr(se.content);try{await Ss(I),Dt(o("chat.messageCopied"))}catch{Dt(o("chat.copyFailed"))}L(null)},[se,Dt,o]),Os=N.useCallback(async()=>{if(!se||se.role!=="user")return;const I=le();if(I===null)return;const O=Jr(se.content);if(!O)return;L(null);const $=se.images?.length?se.images.map((q,fe)=>{const Ie=q.data_url.split(";")[0]?.replace("data:","")||"image/png";return{id:`mobile_resend_${Date.now()}_${fe}`,data_url:q.data_url,mime_type:Ie,metadata:{name:q.name,source:"remote"}}}):void 0;try{if(await e.sendMessage(t,O,"agentic",$),!ce(I))return;y.current?.nudge()}catch(q){Je(q,f)}},[le,ce,se,t,e,f]),Ds=N.useCallback(async()=>{if(se){re(!0);try{Ft.getState().deleteMessage(t,se.id),Dt(o("chat.messageDeleted"))}finally{re(!1),L(null)}}},[se,t,Dt,o]);N.useEffect(()=>()=>{gt(),ve.current&&clearTimeout(ve.current)},[]);const St=N.useRef(!0),bt=N.useRef(!1),jn=N.useRef(!1),Ms=80,Fs=N.useCallback(()=>{const I=Me.current;if(!I)return;const $=I.scrollHeight-I.scrollTop-I.clientHeight0&&ht(q[0].id)}},[xe,ee,a,t,ht]),zs=N.useCallback(()=>{bt.current=!0,St.current=!0,He(!1),jn.current=!1,Xe.current?.scrollIntoView({behavior:"smooth"})},[]),Mt=N.useRef(!1),nn=N.useRef(!1),rn=N.useRef(0);N.useEffect(()=>{Ze.current=!1,Ce.current=!0,_e.current=!1,we(!0),te(!1),T(null),A("primary")},[t]),N.useEffect(()=>{Mt.current=!1,nn.current=!1;const I=++rn.current;let O=!1;const $=le();if($===null)return;const q=()=>!O&&rn.current===I&&ce($);return Promise.all([ht(),lt()]).then(([fe,Ie])=>{if(!q())return;const de=Ft.getState().getMessages(t).length;nn.current=!0;const ae=new Zs(e,t,X=>{q()&&(X.message_snapshot?l(t,X.message_snapshot):X.new_messages&&X.new_messages.length>0&&s(t,X.new_messages),X.total_msg_count!=null&&Ft.getState().getMessages(t).length!==X.total_msg_count&&e.getSessionMessages(t,200).then(nt=>{q()&&Ft.getState().setMessages(t,nt.messages)}).catch(()=>{}),X.title&&(C(X.title),g(t,X.title)),X.model_catalog&&(T(X.model_catalog),A(ut(X.model_catalog.session_model_id,X.model_catalog))),p(X.active_turn??null))},Ie?.version||0);ae.start(de),y.current=ae}),()=>{O=!0,rn.current===I&&(rn.current+=1),y.current?.stop(),y.current=null,p(null)}},[s,le,ce,ht,lt,t,e,p,l,g]);const an=N.useRef(0);N.useLayoutEffect(()=>{if(!nn.current||x.length===0)return;nn.current=!1;const I=Me.current;I&&(I.scrollTop=I.scrollHeight),Mt.current=!0,an.current=x.length},[x]),N.useEffect(()=>{if(Mt.current&&x.length!==an.current){const I=x.length>an.current;an.current=x.length,I&&!ee&&St.current&&(bt.current=!0,Xe.current?.scrollIntoView({behavior:"smooth"}))}},[x.length,ee]),N.useEffect(()=>{!Mt.current||!pe||St.current&&(bt.current=!0,Xe.current?.scrollIntoView({behavior:"auto"}))},[u,pe]),N.useEffect(()=>{G&&(bt.current=!0,St.current=!0,Xe.current?.scrollIntoView({behavior:"smooth"}))},[G]),N.useEffect(()=>{if(!Mt.current||!pe)return;const I=Me.current;if(!I)return;const O=setInterval(()=>{if(!St.current)return;const $=I.scrollHeight-I.scrollTop-I.clientHeight;$>10&&$<400&&(bt.current=!0,I.scrollTo({top:I.scrollHeight,behavior:"smooth"}))},300);return()=>clearInterval(O)},[pe]);const Rn=N.useCallback(async()=>{const I=v.trim(),O=M;if(!I&&O.length===0||P)return;const $=le();if($===null)return;const q=pe;b(""),H([]),q||ie(!1);const fe=O.length>0,Ie=fe?O.map((de,ae)=>{const X=de.dataUrl.split(";")[0]?.replace("data:","")||"image/png";return{id:`mobile_img_${Date.now()}_${ae}`,data_url:de.dataUrl,mime_type:X,metadata:{name:de.name,source:"remote"}}}):void 0;fe&&(J({id:`opt_${Date.now()}`,text:I||"",images:O.map(de=>({name:de.name,data_url:de.dataUrl}))}),z(!0));try{if(await e.sendMessage(t,I||o("chat.imageAttachmentFallback"),"agentic",Ie),!ce($))return;y.current?.nudge(),q&&Ue(o("chat.messageQueued"))}catch(de){Je(de,f)}finally{ce($)&&(z(!1),J(null))}},[le,P,v,ce,pe,M,t,e,f,o]),Ps=N.useCallback(()=>{K.current?.click()},[]),Bs=N.useCallback(async I=>{const O=I.target.files;if(!O)return;const $=5,q=$-M.length,fe=Array.from(O).slice(0,q),{compressImageFile:Ie}=await Xs(async()=>{const{compressImageFile:de}=await import("./imageCompressor-Cy77l5Xt.js");return{compressImageFile:de}},[],import.meta.url);for(const de of fe)try{const ae=await Ie(de);H(X=>X.length>=$?X:[...X,{name:ae.name,dataUrl:ae.dataUrl}])}catch{const ae=new FileReader;ae.onload=()=>{const X=ae.result;H(ue=>ue.length>=$?ue:[...ue,{name:de.name,dataUrl:X}])},ae.readAsDataURL(de)}I.target.value=""},[M.length]),$s=N.useCallback(I=>{H(O=>O.filter(($,q)=>q!==I))},[]),Wi=N.useCallback(()=>{ie(!0),requestAnimationFrame(()=>w.current?.focus())},[]);N.useEffect(()=>{i&&requestAnimationFrame(()=>w.current?.focus())},[i]),N.useEffect(()=>{if(!U)return;const I=O=>{Y.current&&!Y.current.contains(O.target)&&!v.trim()&&M.length===0&&ie(!1)};return document.addEventListener("mousedown",I),()=>document.removeEventListener("mousedown",I)},[U,v,M.length]);const On=N.useRef(!1),qs=N.useCallback(()=>{On.current=!0},[]),Us=N.useCallback(()=>{setTimeout(()=>{On.current=!1},0)},[]),Hs=I=>{if(I.key==="Enter"&&!I.shiftKey){if(I.nativeEvent.isComposing||On.current)return;I.preventDefault(),Rn()}},Ws=async()=>{if(le()!==null)try{await e.cancelTask(t,u?.turn_id)}catch{}},Vi=d?.project_name||d?.path?.split("/").pop()||"",Dn=d?.git_branch,Gi=_||n||o("chat.session");return h.jsxs("div",{className:"chat-page",children:[h.jsx("div",{className:"chat-page__header",children:h.jsxs("div",{className:"chat-page__header-row",children:[h.jsx("button",{className:"chat-page__back",onClick:r,"aria-label":o("common.back"),children:h.jsx("svg",{width:"18",height:"18",viewBox:"0 0 20 20",fill:"none",children:h.jsx("path",{d:"M12 4L6 10L12 16",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsxs("div",{className:"chat-page__header-center",children:[h.jsx("span",{className:"chat-page__title",title:Gi,children:Gi}),Vi&&h.jsxs("div",{className:"chat-page__header-workspace",title:d?.path,children:[h.jsx("span",{className:"chat-page__workspace-name",children:Vi}),Dn&&h.jsxs("span",{className:"chat-page__workspace-branch",title:Dn,children:[h.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("line",{x1:"6",x2:"6",y1:"3",y2:"15"}),h.jsx("circle",{cx:"18",cy:"6",r:"3"}),h.jsx("circle",{cx:"6",cy:"18",r:"3"}),h.jsx("path",{d:"M18 9a9 9 0 0 1-9 9"})]}),wx(Dn,28)]})]})]}),h.jsx("div",{className:"chat-page__header-right",children:h.jsx("button",{className:"chat-page__theme-btn",onClick:S,"aria-label":o("common.toggleTheme"),children:h.jsx(zx,{isDark:k})})})]})}),h.jsxs("div",{className:"chat-page__messages",ref:Me,onScroll:Fs,children:[ee&&h.jsx("div",{className:"chat-page__load-more-indicator",children:o("chat.loadingOlderMessages")}),(()=>{const I=x.reduceRight((O,$,q)=>O<0&&$.role==="user"?q:O,-1);return x.map((O,$)=>{if(O.role==="system"||O.role==="tool")return null;if(O.role==="user"){const ae=Jr(O.content);return h.jsx("div",{className:`chat-msg chat-msg--user${se?.id===O.id?" chat-msg--menu-active":""}`,onTouchStart:X=>mt(O,X),onTouchMove:In,onTouchEnd:wt,onTouchCancel:wt,onContextMenu:X=>{X.preventDefault(),L(O)},children:h.jsxs("div",{className:"chat-msg__user-card",children:[h.jsx("div",{className:"chat-msg__user-avatar",children:"U"}),h.jsxs("div",{className:"chat-msg__user-content",children:[ae,O.images&&O.images.length>0&&h.jsx("div",{className:"chat-msg__user-images",children:O.images.map((X,ue)=>h.jsx("img",{src:X.data_url,alt:X.name,className:"chat-msg__user-image"},ue))})]})]})},O.id)}const q=O.items&&O.items.length>0,fe=O.thinking||O.tools&&O.tools.length>0||O.content;if(!q&&!fe)return null;const Ie=$mt(O,ae),onTouchMove:In,onTouchEnd:wt,onTouchCancel:wt,onContextMenu:ae=>{ae.preventDefault(),L(O)},children:h.jsxs("button",{className:"chat-msg__response-toggle",onClick:()=>Fe(ae=>{const X=new Set(ae);return X.add(O.id),X}),children:[h.jsx("span",{className:"chat-msg__response-chevron",children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M6 4L10 8L6 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsx("span",{className:"chat-msg__response-label",children:o("chat.showResponse")})]})},O.id):h.jsxs("div",{className:`chat-msg chat-msg--assistant${se?.id===O.id?" chat-msg--menu-active":""}`,onTouchStart:ae=>mt(O,ae),onTouchMove:In,onTouchEnd:wt,onTouchCancel:wt,onContextMenu:ae=>{ae.preventDefault(),L(O)},children:[Ie&&de&&h.jsxs("button",{className:"chat-msg__response-toggle",onClick:()=>Fe(ae=>{const X=new Set(ae);return X.delete(O.id),X}),children:[h.jsx("span",{className:"chat-msg__response-chevron is-open",children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("path",{d:"M6 4L10 8L6 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}),h.jsx("span",{className:"chat-msg__response-label",children:o("chat.hideResponse")})]}),q?Vo(O.items,Se,void 0,Le,ye,Ne):h.jsxs(h.Fragment,{children:[O.thinking&&h.jsx(xi,{thinking:O.thinking}),O.tools&&O.tools.length>0&&h.jsx(ki,{tools:O.tools,now:Se}),O.content&&h.jsx("div",{className:"chat-msg__assistant-content",children:h.jsx(Kt,{content:O.content,onFileDownload:ye,onGetFileInfo:Ne})})]})]},O.id)})})(),u&&(()=>{const I=u,O=I.status==="active";if(I.items&&I.items.length>0)return h.jsxs("div",{className:"chat-msg chat-msg--assistant",children:[O?Fx(I.items,Se,e,f,()=>le()!==null,Le,ye,Ne):Vo(I.items,Se,void 0,void 0,ye,Ne),O&&!I.thinking&&!I.text&&I.tools.length===0&&h.jsx("div",{className:"chat-msg__assistant-content",children:h.jsx(ti,{})})]});const $=I.tools.filter(ue=>ue.name==="Task"),q=$.some(ue=>ue.status==="running"),fe=I.tools.filter(ue=>ue.name==="AskUserQuestion"&&ue.status==="running"&&ue.tool_input),Ie=new Set(fe.map(ue=>ue.id)),de=I.tools.filter(ue=>ue.name!=="Task"&&!Ie.has(ue.id)),ae=q?[...I.thinking?[{type:"thinking",content:I.thinking}]:[],...de.map(ue=>({type:"tool",tool:ue}))]:[],X=ue=>{le()!==null&&e.cancelTool(ue,o("common.cancel")).catch(nt=>{Je(nt,f)})};return h.jsxs("div",{className:"chat-msg chat-msg--assistant",children:[!q&&(I.thinking||O)&&h.jsx(xi,{thinking:I.thinking,streaming:O,isLastItem:O}),$.map(ue=>h.jsx(_s,{tool:ue,now:Se,subItems:ue.status==="running"?ae:void 0,onCancelTool:X},ue.id)),!q&&de.length>0&&h.jsx(ki,{tools:de,now:Se,onCancelTool:X}),O&&fe.map(ue=>h.jsx(As,{tool:ue,onAnswer:Le},ue.id)),!q&&I.text?h.jsx("div",{className:"chat-msg__assistant-content",children:O?h.jsx(Ts,{content:I.text,onFileDownload:ye,onGetFileInfo:Ne}):h.jsx(Kt,{content:I.text,onFileDownload:ye,onGetFileInfo:Ne})}):O&&!I.thinking&&I.tools.length===0?h.jsx("div",{className:"chat-msg__assistant-content",children:h.jsx(ti,{})}):null]})})(),G&&h.jsx("div",{className:"chat-msg chat-msg--user",children:h.jsxs("div",{className:"chat-msg__user-card",children:[h.jsx("div",{className:"chat-msg__user-avatar",children:"U"}),h.jsxs("div",{className:"chat-msg__user-content",children:[G.text,G.images.length>0&&h.jsx("div",{className:"chat-msg__user-images",children:G.images.map((I,O)=>h.jsx("img",{src:I.data_url,alt:I.name,className:"chat-msg__user-image"},O))})]})]})}),P&&h.jsx("div",{className:"chat-msg chat-msg--assistant",children:h.jsx("div",{className:"chat-msg__assistant-card",children:h.jsxs("div",{className:"chat-msg__image-analyzing",children:[h.jsx("div",{className:"chat-msg__image-analyzing-icon",children:h.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("circle",{cx:"12",cy:"12",r:"3"}),h.jsx("path",{d:"M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"})]})}),h.jsx("span",{children:o("chat.analyzingImage")}),h.jsx(ti,{})]})})}),h.jsx("div",{ref:Xe})]}),ft&&h.jsx("button",{type:"button",className:"chat-page__scroll-to-bottom",onClick:zs,"aria-label":o("chat.scrollToBottom"),children:h.jsx("svg",{"aria-hidden":"true",focusable:"false",width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:h.jsx("polyline",{points:"6 9 12 15 18 9"})})}),se&&h.jsx("div",{className:"chat-msg__menu-overlay",onClick:()=>L(null),children:h.jsxs("div",{className:"chat-msg__menu-sheet",onClick:I=>I.stopPropagation(),children:[h.jsx("div",{className:"chat-msg__menu-handle"}),h.jsxs("div",{className:"chat-msg__menu-actions",children:[h.jsxs("button",{className:"chat-msg__menu-btn",onClick:Rs,children:[h.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),h.jsx("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]}),h.jsx("span",{children:o("chat.copyMessage")})]}),se.role==="user"&&h.jsxs("button",{className:"chat-msg__menu-btn",onClick:Os,children:[h.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("polyline",{points:"23 4 23 10 17 10"}),h.jsx("path",{d:"M20.49 15a9 9 0 1 1-2.12-9.36L23 10"})]}),h.jsx("span",{children:o("chat.resendMessage")})]}),h.jsxs("button",{className:"chat-msg__menu-btn chat-msg__menu-btn--danger",onClick:Ds,disabled:V,children:[h.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("polyline",{points:"3 6 5 6 21 6"}),h.jsx("path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"})]}),h.jsx("span",{children:V?"...":o("chat.deleteMessage")})]})]}),h.jsx("button",{className:"chat-msg__menu-cancel",onClick:()=>L(null),children:o("common.cancel")})]})}),D&&h.jsx("div",{className:"chat-page__toast",role:"alert","aria-live":"assertive",children:D}),h.jsx("input",{ref:K,type:"file",accept:"image/png,image/jpeg,image/jpg,image/gif,image/webp",multiple:!0,style:{display:"none"},onChange:Bs}),h.jsx("div",{className:`chat-page__input-wrap ${U?"is-expanded":""}`,ref:Y,children:h.jsxs("div",{className:"chat-page__input-box",onClick:U?void 0:Wi,children:[h.jsx("div",{className:"chat-page__input-area",children:U?h.jsx("textarea",{ref:w,className:"chat-page__input",placeholder:o("chat.inputPlaceholder"),value:v,onChange:I=>b(I.target.value),onKeyDown:Hs,onCompositionStart:qs,onCompositionEnd:Us,rows:1,disabled:P}):h.jsx("span",{className:"chat-page__input-placeholder",children:o(P?"chat.imageAnalyzingPlaceholder":pe?"chat.collapsedStreamingPlaceholder":"chat.collapsedInputPlaceholder")})}),h.jsxs("div",{className:"chat-page__input-actions",children:[h.jsxs("div",{className:"chat-page__input-actions-left",children:[U&&h.jsxs(h.Fragment,{children:[h.jsx(Wx,{catalog:m,selectedModelId:j,disabled:P||pe||E,onSelect:Nn}),h.jsx(Vx,{catalog:m,selectedModelId:j,disabled:P||pe||E,onSelect:tn})]}),U&&M.length>0&&h.jsx("div",{className:"chat-page__image-preview-row",children:M.map((I,O)=>h.jsxs("div",{className:"chat-page__image-thumb",children:[h.jsx("img",{src:I.dataUrl,alt:I.name}),h.jsx("button",{className:"chat-page__image-remove",onClick:()=>$s(O),children:"×"})]},O))})]}),h.jsxs("div",{className:"chat-page__input-actions-right",children:[U&&h.jsx("button",{className:"chat-page__action-btn",onClick:Ps,disabled:P||M.length>=5,"aria-label":o("common.attachImage"),children:h.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[h.jsx("rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",ry:"2"}),h.jsx("circle",{cx:"9",cy:"9",r:"2"}),h.jsx("path",{d:"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"})]})}),P?h.jsx("button",{className:"chat-page__send-btn is-stop","aria-label":o("common.stop"),disabled:!0,children:h.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",style:{animation:"analyzeSpin 2s linear infinite"},children:[h.jsx("circle",{cx:"12",cy:"12",r:"3"}),h.jsx("path",{d:"M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2"})]})}):pe?h.jsxs("div",{className:"chat-page__stream-actions",children:[h.jsx("button",{type:"button",className:"chat-page__send-btn is-stop",onClick:Ws,"aria-label":o("common.stop"),children:h.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:h.jsx("rect",{x:"3",y:"3",width:"10",height:"10",rx:"2",fill:"currentColor"})})}),h.jsx("button",{type:"button",className:"chat-page__send-btn",onClick:U?Rn:Wi,disabled:!v.trim()&&M.length===0,"aria-label":o("common.submit"),children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 20 20",fill:"none",children:h.jsx("path",{d:"M10 3L10 17M10 3L5 8M10 3L15 8",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]}):h.jsx("button",{className:"chat-page__send-btn",onClick:U?Rn:void 0,disabled:!v.trim()&&M.length===0,children:h.jsx("svg",{width:"12",height:"12",viewBox:"0 0 20 20",fill:"none",children:h.jsx("path",{d:"M10 3L10 17M10 3L5 8M10 3L15 8",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]})]})]})}),c&&h.jsx("div",{className:"chat-page__toast",onClick:()=>f(null),children:c}),Qe&&h.jsx("div",{className:"chat-page__toast chat-page__toast--info",onClick:()=>Ue(null),children:Qe})]})};export{Zx as default};
diff --git a/src/apps/relay-server/static/assets/index-BNRAmblM.js b/src/apps/relay-server/static/assets/index-BNRAmblM.js
deleted file mode 100644
index 820a3e352f..0000000000
--- a/src/apps/relay-server/static/assets/index-BNRAmblM.js
+++ /dev/null
@@ -1,9 +0,0 @@
-(function(){const l=document.createElement("link").relList;if(l&&l.supports&&l.supports("modulepreload"))return;for(const f of document.querySelectorAll('link[rel="modulepreload"]'))d(f);new MutationObserver(f=>{for(const m of f)if(m.type==="childList")for(const p of m.addedNodes)p.tagName==="LINK"&&p.rel==="modulepreload"&&d(p)}).observe(document,{childList:!0,subtree:!0});function a(f){const m={};return f.integrity&&(m.integrity=f.integrity),f.referrerPolicy&&(m.referrerPolicy=f.referrerPolicy),f.crossOrigin==="use-credentials"?m.credentials="include":f.crossOrigin==="anonymous"?m.credentials="omit":m.credentials="same-origin",m}function d(f){if(f.ep)return;f.ep=!0;const m=a(f);fetch(f.href,m)}})();let fi="dark";try{const o=localStorage.getItem("bitfun-mobile-theme");(o==="dark"||o==="light")&&(fi=o)}catch{window.matchMedia?.("(prefers-color-scheme: light)").matches&&(fi="light")}document.documentElement.setAttribute("data-theme",fi);document.documentElement.style.colorScheme=fi;var Mg=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Fd(o){return o&&o.__esModule&&Object.prototype.hasOwnProperty.call(o,"default")?o.default:o}var Xl={exports:{}},Ms={},Jl={exports:{}},we={};var Xc;function nh(){if(Xc)return we;Xc=1;var o=Symbol.for("react.element"),l=Symbol.for("react.portal"),a=Symbol.for("react.fragment"),d=Symbol.for("react.strict_mode"),f=Symbol.for("react.profiler"),m=Symbol.for("react.provider"),p=Symbol.for("react.context"),_=Symbol.for("react.forward_ref"),w=Symbol.for("react.suspense"),E=Symbol.for("react.memo"),I=Symbol.for("react.lazy"),j=Symbol.iterator;function R(v){return v===null||typeof v!="object"?null:(v=j&&v[j]||v["@@iterator"],typeof v=="function"?v:null)}var B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},F=Object.assign,$={};function W(v,T,re){this.props=v,this.context=T,this.refs=$,this.updater=re||B}W.prototype.isReactComponent={},W.prototype.setState=function(v,T){if(typeof v!="object"&&typeof v!="function"&&v!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,v,T,"setState")},W.prototype.forceUpdate=function(v){this.updater.enqueueForceUpdate(this,v,"forceUpdate")};function de(){}de.prototype=W.prototype;function b(v,T,re){this.props=v,this.context=T,this.refs=$,this.updater=re||B}var K=b.prototype=new de;K.constructor=b,F(K,W.prototype),K.isPureReactComponent=!0;var se=Array.isArray,_e=Object.prototype.hasOwnProperty,fe={current:null},ke={key:!0,ref:!0,__self:!0,__source:!0};function Se(v,T,re){var ue,pe={},ce=null,te=null;if(T!=null)for(ue in T.ref!==void 0&&(te=T.ref),T.key!==void 0&&(ce=""+T.key),T)_e.call(T,ue)&&!ke.hasOwnProperty(ue)&&(pe[ue]=T[ue]);var ge=arguments.length-2;if(ge===1)pe.children=re;else if(1>>1,T=D[v];if(0>>1;vf(pe,L))cef(te,pe)?(D[v]=te,D[ce]=L,v=ce):(D[v]=pe,D[ue]=L,v=ue);else if(cef(te,L))D[v]=te,D[ce]=L,v=ce;else break e}}return O}function f(D,O){var L=D.sortIndex-O.sortIndex;return L!==0?L:D.id-O.id}if(typeof performance=="object"&&typeof performance.now=="function"){var m=performance;o.unstable_now=function(){return m.now()}}else{var p=Date,_=p.now();o.unstable_now=function(){return p.now()-_}}var w=[],E=[],I=1,j=null,R=3,B=!1,F=!1,$=!1,W=typeof setTimeout=="function"?setTimeout:null,de=typeof clearTimeout=="function"?clearTimeout:null,b=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function K(D){for(var O=a(E);O!==null;){if(O.callback===null)d(E);else if(O.startTime<=D)d(E),O.sortIndex=O.expirationTime,l(w,O);else break;O=a(E)}}function se(D){if($=!1,K(D),!F)if(a(w)!==null)F=!0,ae(_e);else{var O=a(E);O!==null&&ne(se,O.startTime-D)}}function _e(D,O){F=!1,$&&($=!1,de(Se),Se=-1),B=!0;var L=R;try{for(K(O),j=a(w);j!==null&&(!(j.expirationTime>O)||D&&!Ce());){var v=j.callback;if(typeof v=="function"){j.callback=null,R=j.priorityLevel;var T=v(j.expirationTime<=O);O=o.unstable_now(),typeof T=="function"?j.callback=T:j===a(w)&&d(w),K(O)}else d(w);j=a(w)}if(j!==null)var re=!0;else{var ue=a(E);ue!==null&&ne(se,ue.startTime-O),re=!1}return re}finally{j=null,R=L,B=!1}}var fe=!1,ke=null,Se=-1,Te=5,Me=-1;function Ce(){return!(o.unstable_now()-MeD||125v?(D.sortIndex=L,l(E,D),a(w)===null&&D===a(E)&&($?(de(Se),Se=-1):$=!0,ne(se,L-v))):(D.sortIndex=T,l(w,D),F||B||(F=!0,ae(_e))),D},o.unstable_shouldYield=Ce,o.unstable_wrapCallback=function(D){var O=R;return function(){var L=R;R=O;try{return D.apply(this,arguments)}finally{R=L}}}})(na)),na}var rd;function ih(){return rd||(rd=1,ta.exports=oh()),ta.exports}var sd;function lh(){if(sd)return yt;sd=1;var o=xa(),l=ih();function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),w=Object.prototype.hasOwnProperty,E=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,I={},j={};function R(e){return w.call(j,e)?!0:w.call(I,e)?!1:E.test(e)?j[e]=!0:(I[e]=!0,!1)}function B(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return r?!1:n!==null?!n.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function F(e,t,n,r){if(t===null||typeof t>"u"||B(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function $(e,t,n,r,s,i,c){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=s,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=i,this.removeEmptyString=c}var W={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){W[e]=new $(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];W[t]=new $(t,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){W[e]=new $(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){W[e]=new $(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){W[e]=new $(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){W[e]=new $(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){W[e]=new $(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){W[e]=new $(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){W[e]=new $(e,5,!1,e.toLowerCase(),null,!1,!1)});var de=/[\-:]([a-z])/g;function b(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(de,b);W[t]=new $(t,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(de,b);W[t]=new $(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(de,b);W[t]=new $(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){W[e]=new $(e,1,!1,e.toLowerCase(),null,!1,!1)}),W.xlinkHref=new $("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){W[e]=new $(e,1,!1,e.toLowerCase(),null,!0,!0)});function K(e,t,n,r){var s=W.hasOwnProperty(t)?W[t]:null;(s!==null?s.type!==0:r||!(2h||s[c]!==i[h]){var g=`
-`+s[c].replace(" at new "," at ");return e.displayName&&g.includes("")&&(g=g.replace("",e.displayName)),g}while(1<=c&&0<=h);break}}}finally{re=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?T(e):""}function pe(e){switch(e.tag){case 5:return T(e.type);case 16:return T("Lazy");case 13:return T("Suspense");case 19:return T("SuspenseList");case 0:case 2:case 15:return e=ue(e.type,!1),e;case 11:return e=ue(e.type.render,!1),e;case 1:return e=ue(e.type,!0),e;default:return""}}function ce(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case ke:return"Fragment";case fe:return"Portal";case Te:return"Profiler";case Se:return"StrictMode";case Q:return"Suspense";case q:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case Ce:return(e.displayName||"Context")+".Consumer";case Me:return(e._context.displayName||"Context")+".Provider";case me:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case ee:return t=e.displayName||null,t!==null?t:ce(e.type)||"Memo";case ae:t=e._payload,e=e._init;try{return ce(e(t))}catch{}}return null}function te(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return ce(t);case 8:return t===Se?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function ge(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function ye(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function De(e){var t=ye(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var s=n.get,i=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return s.call(this)},set:function(c){r=""+c,i.call(this,c)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(c){r=""+c},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function ct(e){e._valueTracker||(e._valueTracker=De(e))}function kt(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=ye(e)?e.checked?"true":"false":e.value),e=r,e!==n?(t.setValue(e),!0):!1}function ze(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function $e(e,t){var n=t.checked;return L({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function Ie(e,t){var n=t.defaultValue==null?"":t.defaultValue,r=t.checked!=null?t.checked:t.defaultChecked;n=ge(t.value!=null?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function He(e,t){t=t.checked,t!=null&&K(e,"checked",t,!1)}function Ve(e,t){He(e,t);var n=ge(t.value),r=t.type;if(n!=null)r==="number"?(n===0&&e.value===""||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if(r==="submit"||r==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?Ye(e,t.type,n):t.hasOwnProperty("defaultValue")&&Ye(e,t.type,ge(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function jt(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!(r!=="submit"&&r!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,n!==""&&(e.name=n)}function Ye(e,t,n){(t!=="number"||ze(e.ownerDocument)!==e)&&(n==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var nt=Array.isArray;function $t(e,t,n,r){if(e=e.options,t){t={};for(var s=0;s"+t.valueOf().toString()+"",t=St.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function Tt(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var Ee={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},le=["Webkit","ms","Moz","O"];Object.keys(Ee).forEach(function(e){le.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Ee[t]=Ee[e]})});function hr(e,t,n){return t==null||typeof t=="boolean"||t===""?"":n||typeof t!="number"||t===0||Ee.hasOwnProperty(e)&&Ee[e]?(""+t).trim():t+"px"}function Xr(e,t){e=e.style;for(var n in t)if(t.hasOwnProperty(n)){var r=n.indexOf("--")===0,s=hr(n,t[n],r);n==="float"&&(n="cssFloat"),r?e.setProperty(n,s):e[n]=s}}var Xn=L({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function mr(e,t){if(t){if(Xn[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(a(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(a(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(a(61))}if(t.style!=null&&typeof t.style!="object")throw Error(a(62))}}function gr(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var Tn=null;function vr(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var un=null,cn=null,dn=null;function fn(e){if(e=_s(e)){if(typeof un!="function")throw Error(a(280));var t=e.stateNode;t&&(t=mo(t),un(e.stateNode,e.type,t))}}function In(e){cn?dn?dn.push(e):dn=[e]:cn=e}function pn(){if(cn){var e=cn,t=dn;if(dn=cn=null,fn(e),t)for(e=0;e>>=0,e===0?32:31-(yf(e)/wf|0)|0}var Gs=64,Zs=4194304;function ns(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Xs(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,s=e.suspendedLanes,i=e.pingedLanes,c=n&268435455;if(c!==0){var h=c&~s;h!==0?r=ns(h):(i&=c,i!==0&&(r=ns(i)))}else c=n&~s,c!==0?r=ns(c):i!==0&&(r=ns(i));if(r===0)return 0;if(t!==0&&t!==r&&(t&s)===0&&(s=r&-r,i=t&-t,s>=i||s===16&&(i&4194240)!==0))return t;if((r&4)!==0&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0